/* Лекторий — оформление мини-приложения.

   Ключевое решение: у приложения СВОЯ палитра, а не переменные телеграма.
   Пока интерфейс красился темой клиента, в тёмном оформлении всё сливалось
   в одинаковую серую массу — фон, карточки и разделители оказывались почти
   одного тона. Тема телеграма даёт совместимость, но не даёт характера,
   а характер здесь и есть продукт.

   Из клиента берём только светлое оно или тёмное — остальное своё. */

:root {
  /* Светлое оформление: холодновато-серый стол, на котором лежит тёплая
     бумага. Контраст между ними и делает лист листом. */
  --ground: #EAECF2;
  --ground-deep: #DCE0E9;
  --card: #FFFFFF;
  --text: #14171F;
  --text-soft: #545C6B;
  /* Служебная подпись — не «еле видно»: #8A93A4 давал 3.1:1 на карточке и
     2.6:1 на столе, и «6 лекций» под книгой читалось только вплотную. */
  --hint: #5F6879;
  --line: rgba(20, 24, 32, 0.09);
  --accent: #0F766E;
  --accent-soft: #DCF1EE;
  --accent-text: #FFFFFF;
  --danger: #DC2626;

  --paper: #FCFAF4;
  --ink: #16181D;
  --ink-soft: #565E6E;
  --rule: rgba(31, 58, 92, 0.09);
  --paper-rule: rgba(31, 58, 92, 0.10);
  --margin-line: rgba(198, 84, 74, 0.28);
  /* Чип — плашка ПОВЕРХ поверхности: код, термин, бейдж, фон формулы.
     Раньше её роль играл --ground-deep, но это «углубление стола»: в тёмном
     оформлении он #080A0D и превращал код на бумаге #1E232B в чёрную дыру. */
  --chip: #E8EAF0;
  --chip-paper: rgba(31, 58, 92, 0.055);
  /* Служебные подписи ЛИСТА красятся чернилами бумаги, а не серым интерфейса:
     --hint на тёплом #FCFAF4 давал 3.0:1 и на ходу просто исчезал. */
  --paper-label: #6B6257;
  --paper-tint: #F6F2E7;
  --exam: #FDF0C4;
  --exam-line: #E9C46A;
  --exam-text: #8A5B12;

  --shadow-sm: 0 1px 2px rgba(16, 22, 34, 0.06);
  --shadow-md: 0 2px 6px rgba(16, 22, 34, 0.07), 0 10px 22px -12px rgba(16, 22, 34, 0.30);
  --shadow-lg: 0 4px 12px rgba(16, 22, 34, 0.10), 0 18px 34px -18px rgba(16, 22, 34, 0.40);

  --sab: max(env(safe-area-inset-bottom, 0px), var(--tg-safe-area-inset-bottom, 0px));
  /* В полноэкранном режиме телеграм рисует свои кнопки поверх верха страницы —
     контентный отступ учитывает и вырез экрана, и эти кнопки. */
  --sat: max(env(safe-area-inset-top, 0px),
             calc(var(--tg-safe-area-inset-top, 0px) + var(--tg-content-safe-area-inset-top, 0px)));
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --serif: "PT Serif", Georgia, "Times New Roman", serif;
  /* Безразмерный интерлиньяж: на ноутбуке кегль листа больше, и жёсткие 28px
     там душили строку. Шаг линовки считается из него же — линовка и текст
     обязаны стоять на одной сетке. */
  --line-h: 1.78;
  --sheet-fs: 15.5px;
  --rule-step: calc(var(--sheet-fs) * var(--line-h));
  --radius: 14px;
}

/* Тёмное оформление собрано отдельно, а не выведено инверсией: бумага
   обязана остаться СВЕТЛЕЕ фона, иначе лист читается как дырка в экране. */
html.dark {
  --ground: #0D1014;
  --ground-deep: #080A0D;
  --card: #171B21;
  --text: #ECEEF2;
  --text-soft: #A4ADBC;
  --hint: #8B95A6;   /* 5.7:1 на карточке; прежний #6D7787 давал 3.8:1 */
  --line: rgba(255, 255, 255, 0.08);
  --accent: #2DD4BF;
  --accent-soft: rgba(45, 212, 191, 0.13);
  --accent-text: #04201C;
  --danger: #F87171;

  --paper: #1E232B;
  --ink: #ECE9E1;
  --ink-soft: #A7AFBE;
  --rule: rgba(255, 255, 255, 0.055);
  --paper-rule: rgba(255, 255, 255, 0.042);
  --margin-line: rgba(220, 110, 100, 0.24);
  --chip: rgba(255, 255, 255, 0.075);
  --chip-paper: rgba(255, 255, 255, 0.05);
  --paper-label: #C0B7A4;   /* «цитата» на жёлтом чипе давала 3.7:1, теперь 5.0:1 */
  --paper-tint: rgba(255, 255, 255, 0.035);
  --exam: rgba(233, 196, 106, 0.14);
  --exam-line: rgba(233, 196, 106, 0.5);
  --exam-text: #F5D68A;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.5), 0 12px 26px -14px rgba(0, 0, 0, 0.8);
  --shadow-lg: 0 6px 16px rgba(0, 0, 0, 0.55), 0 22px 40px -20px rgba(0, 0, 0, 0.9);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

body {
  margin: 0;
  font-family: var(--sans);
  background: var(--ground);
  color: var(--text);
  min-height: var(--tg-viewport-stable-height, 100dvh);
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
}

button { font-family: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.stage-empty { display: none; }
.screen { display: none; padding-bottom: calc(24px + var(--sab)); }
.screen.active { display: block; }

/* ── Полка ────────────────────────────────────────────────────────────────
   Под шапкой лежит мягкое пятно акцентного цвета, чтобы полка не выглядела
   плоской заливкой. */

.shelf {
  padding: calc(16px + var(--sat)) 15px 20px;
  min-height: 100%;
  background: radial-gradient(120% 38% at 50% -6%, var(--accent-soft), transparent 62%);
}

.head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}
.head h1 {
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 700;
  margin: 0;
  letter-spacing: -0.015em;
}

.search {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 11px 14px;
  font-size: 15px;
  background: var(--card);
  color: var(--text);
  margin-bottom: 20px;
  box-shadow: var(--shadow-sm);
}
.search::placeholder { color: var(--hint); }
.search:focus { border-color: var(--accent); outline: none; }

.label {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hint);
  margin: 0 2px 10px;
}

.working {
  background: var(--card);
  border-radius: var(--radius);
  padding: 13px 14px;
  margin-bottom: 10px;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--line);
}
.working .row { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.working .name { font-size: 14.5px; font-weight: 600; }
.working .pct { font-size: 13px; color: var(--accent); font-variant-numeric: tabular-nums; font-weight: 600; }
.working .stage { font-size: 12.5px; color: var(--text-soft); margin-top: 3px; }
#working-wrap { margin-bottom: 22px; }

.bar { height: 6px; border-radius: 3px; background: var(--ground-deep); margin-top: 10px; overflow: hidden; }
.bar i {
  display: block; height: 100%; border-radius: 3px;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 55%, #ffffff));
  transition: width .45s ease;
}

.head-add {
  width: 36px; height: 36px;
  border: 0;
  border-radius: 50%;
  background: var(--card);
  color: var(--accent);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  display: grid;
  place-items: center;
}

/* display:grid перебивает атрибут hidden, и спрятанные кнопки оставались на
   экране. Видно это было на постороннем: приложение объясняло, что его нет в
   списке, а «＋» и лампочка рядом предлагали завести предмет и спросить
   ассистента — то есть получить ещё два отказа подряд. */
.head-add[hidden] { display: none; }

/* Три книги в ряд: так это читается как полка, а не как две плиты
   на полэкрана. Под каждым рядом — доска, на которой книги стоят. */
.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px 12px;
  padding: 0 2px;
  /* Кнопка центрирует содержимое по вертикали, и книга без подписи
     сползала ниже соседей — прижимаем все книги к верху ряда. */
  align-items: start;
}

.book { background: none; border: 0; padding: 0; text-align: left; cursor: pointer; position: relative; }

/* Обложка. Названия — на бумажной наклейке, как на настоящей тетради:
   так текст читается на обложке любого цвета и не нужны тени под буквами. */
.cover {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: 2px 7px 7px 2px;
  box-shadow: var(--shadow-md), inset -1px 0 0 rgba(255,255,255,.12);
  overflow: hidden;
  transition: transform .18s ease;
}
.book:active .cover { transform: translateY(2px); }
.cover::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 9px;
  background: linear-gradient(90deg, rgba(0,0,0,.42), rgba(0,0,0,.12) 55%, rgba(255,255,255,.14) 100%);
}
.cover::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(165deg, rgba(255,255,255,.18), transparent 42%, rgba(0,0,0,.10));
  pointer-events: none;
}
.cover span {
  position: absolute;
  z-index: 1;
  left: 19%; right: 11%; bottom: 13%;
  background: #FBF7EA;
  color: #1B1A17;
  border-radius: 3px;
  /* По бокам тесно: «Матанализ» — одно слово во всю наклейку, и лишние
     два пикселя решают, влезет оно целиком или потеряет последнюю букву. */
  padding: 6px 4px 7px;
  font-family: var(--serif);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.25;
  box-shadow: 0 1px 2px rgba(0,0,0,.25), inset 0 0 0 1px rgba(0,0,0,.06);
  overflow: hidden;
}
/* Обрезаем длинное название на вложенном элементе, а не на самой наклейке.
   Наклейка лежит абсолютом, а абсолюту браузер переписывает display на
   блочный — вместе с ним отваливалась и обрезка по строкам: многоточие
   в конце второй строки уже стояло, но третья всё равно вылезала в нижнее
   поле наклейки и обрезалась по живому. «Поток-проверка-доски» на полке
   читался как «Поток-проверк…» и половина слова «доски» под ним. */
.cover span i {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-style: normal;
  /* Слово длиннее наклейки лучше перенести, чем разрезать пополам. */
  overflow-wrap: anywhere;
}
.cover em {
  position: absolute;
  z-index: 1;
  top: 9px; right: 9px;
  font-style: normal;
  font-size: 16px;
  line-height: 1;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,.35);
  opacity: .95;
}

/* Полка под рядом книг: сегменты соседних книг стыкуются в одну доску. */
.book::after {
  content: "";
  position: absolute;
  left: -6px; right: -6px;
  top: calc(100% - 22px);
  height: 7px;
  border-radius: 1px;
  background: linear-gradient(180deg, #D9CDB6, #B9A98F);
  box-shadow: 0 4px 6px -2px rgba(0,0,0,.28);
  z-index: -1;
}
html.dark .book::after {
  background: linear-gradient(180deg, #3B4049, #22262C);
  box-shadow: 0 5px 8px -2px rgba(0,0,0,.7);
}
.book .meta { margin-top: 12px; padding-left: 2px; }
.book .meta small { font-size: 11.5px; color: var(--hint); }

/* «Новый предмет» — прозрачная книга-призрак на той же полке. */
.cover-add {
  aspect-ratio: 3 / 4;
  border-radius: 2px 7px 7px 2px;
  border: 1.5px dashed var(--hint);
  opacity: .55;
  display: grid;
  place-content: center;
  gap: 5px;
  color: var(--text-soft);
  text-align: center;
  transition: opacity .18s;
}
.cover-add span { font-size: 22px; line-height: 1; }
.cover-add small { font-size: 10.5px; line-height: 1.2; padding: 0 6px; }
.add-book:active .cover-add { opacity: 1; }

.empty { text-align: center; padding: 22px 6px 8px; color: var(--text-soft); }
.empty h2 { font-size: 20px; color: var(--text); margin: 0 0 6px; font-family: var(--serif); letter-spacing: -.01em; }
.empty p { font-size: 14px; line-height: 1.55; margin: 0 auto; max-width: 30ch; }

/* ── Лекции предмета ──────────────────────────────────────────────────── */

/* Шапка предмета липнет к верху. «Плюс» в ней обещан всегда — а список
   лекций у предмета длиннее экрана уже на четвёртой паре, и вместе со
   списком уезжал и он: добавить вторую доску можно было, только домотав
   обратно наверх. */
.subject-head {
  display: flex;
  gap: 14px;
  align-items: center;
  padding: calc(16px + var(--sat)) 15px 16px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  /* Ниже плеера (10) и всего плавающего: карточки уходят под шапку, а
     кнопка записи и всплывашки остаются поверх неё. */
  z-index: 9;
}
.subject-head .mini {
  width: 46px; height: 61px; flex: none;
  border-radius: 2px 8px 8px 2px;
  box-shadow: var(--shadow-md);
}
.subject-head h2 { margin: 0 0 3px; font-size: 19px; font-weight: 700; font-family: var(--serif); }
.subject-head small { color: var(--hint); font-size: 12.5px; }

.list { padding: 15px; display: grid; gap: 11px; }
.card {
  position: relative;
  background: var(--card);
  border-radius: var(--radius);
  padding: 13px 15px 13px 18px;
  cursor: pointer;
  border: 1px solid var(--line);
  text-align: left;
  width: 100%;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform .15s ease;
}
.card:active { transform: scale(.99); }
.card::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--accent);
}
.card .title { font-size: 15.5px; font-weight: 600; margin-bottom: 5px; }
.card .sub { font-size: 12px; color: var(--hint); display: flex; gap: 7px; flex-wrap: wrap; align-items: center; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  padding: 3px 8px;
  border-radius: 7px;
  background: var(--chip);
  color: var(--text-soft);
}
.badge.warn { background: var(--exam); color: var(--exam-text); }
.badge.fail { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }

/* ── Лист конспекта ───────────────────────────────────────────────────── */

.sheet-wrap { padding: 14px 11px calc(90px + var(--sab)); }
/* Лист — как тетрадный разворот: тёплая бумага, поля с красной чертой,
   светлая линовка по тому же шагу, что и строка текста, и мягкий свет
   сверху, чтобы бумага не выглядела заливкой. Линовка нарочно на грани
   видимости: она даёт фактуру, но не спорит с формулами. */
.sheet {
  background-color: var(--paper);
  background-image:
    repeating-linear-gradient(to bottom,
      transparent 0, transparent calc(var(--rule-step) - 1px),
      var(--paper-rule) calc(var(--rule-step) - 1px), var(--paper-rule) var(--rule-step)),
    linear-gradient(180deg, rgba(255, 255, 255, .55), rgba(255, 255, 255, 0) 180px),
    radial-gradient(130% 70% at 100% 0, rgba(190, 150, 80, .07), transparent 60%);
  background-position: 0 calc(var(--sheet-top) + var(--rule-step) * .82), 0 0, 0 0;
  color: var(--ink);
  border-radius: 3px 14px 14px 3px;
  --sheet-top: 24px;
  padding: var(--sheet-top) 20px 32px 32px;
  position: relative;
  font-family: var(--serif);
  box-shadow: var(--shadow-lg);
  /* Русские термины на 42 знака в строке рвали правый край. */
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
}
html.dark .sheet {
  background-image:
    repeating-linear-gradient(to bottom,
      transparent 0, transparent calc(var(--rule-step) - 1px),
      var(--paper-rule) calc(var(--rule-step) - 1px), var(--paper-rule) var(--rule-step)),
    linear-gradient(180deg, rgba(255, 255, 255, .045), rgba(255, 255, 255, 0) 180px),
    radial-gradient(130% 70% at 100% 0, rgba(255, 220, 160, .045), transparent 60%);
}
/* Левое поле: красная черта и тонкая тень сгиба у корешка. */
.sheet::before {
  content: "";
  position: absolute;
  left: 22px; top: 0; bottom: 0;
  width: 1px;
  background: var(--margin-line);
}
.sheet::after {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 10px;
  border-radius: 3px 0 0 3px;
  background: linear-gradient(90deg, rgba(90, 70, 40, .10), transparent);
  pointer-events: none;
}
html.dark .sheet::after { background: linear-gradient(90deg, rgba(0, 0, 0, .35), transparent); }

.sheet-head {
  font-family: var(--sans);
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--paper-label);
  font-weight: 700;
}
/* Кегельный контраст: заголовок лекции крупный и плотный, подзаголовок
   раздела заметно мельче, но с воздухом сверху — иначе он читался как
   продолжение предыдущего абзаца. */
.sheet h1 {
  font-size: 27px;
  line-height: 1.16;
  margin: 10px 0 6px;
  text-wrap: balance;
  letter-spacing: -0.018em;
  hyphens: none;
}
.sheet h2 {
  font-size: 18.5px;
  margin: 24px 0 8px;
  line-height: 1.28;
  letter-spacing: -0.012em;
  hyphens: none;
}
.sheet h3 { font-size: 15.5px; margin: 18px 0 6px; letter-spacing: -0.005em; hyphens: none; }
/* Первый заголовок блока не отбивается: сверху уже стоит метка блока. */
.block > h2:first-child, .block-label + h2 { margin-top: 0; }
.sheet p { font-size: var(--sheet-fs); line-height: var(--line-h); margin: 0 0 8px; }
.sheet ul, .sheet ol { padding-left: 21px; margin: 4px 0 9px; }
.sheet li { font-size: var(--sheet-fs); line-height: var(--line-h); margin-bottom: 5px; }
.sheet strong, .sheet b { font-weight: 700; }
.sheet em, .sheet i { font-style: italic; }
.sheet code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  background: var(--chip-paper);
  padding: 1px 5px;
  border-radius: 5px;
}
.coverage {
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--paper-label);
  margin: 0 0 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
}

/* Тайм-код — единственный переход «текст → место в записи». Полоской в 13px
   в него не попасть пальцем: это кнопка, и выглядеть она должна кнопкой. */
.timecode {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
  font-family: var(--sans);
  font-size: 11.5px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  background: var(--accent-soft);
  border: 0;
  padding: 3px 9px 3px 7px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  vertical-align: middle;
  transition: transform .12s ease, background .15s ease;
}
.timecode::before {
  content: "";
  width: 11px; height: 11px;
  flex: none;
  background: currentColor;
  -webkit-mask: var(--ic-play) center / 11px 11px no-repeat;
  mask: var(--ic-play) center / 11px 11px no-repeat;
}
.timecode:active { transform: scale(.94); }

.editor {
  width: 100%;
  min-height: 62vh;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 15.5px;
  line-height: var(--line-h);
  resize: none;
  padding: 0;
}
.editor:focus { outline: none; }

/* ── Плеер ────────────────────────────────────────────────────────────── */

.player {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(12px + var(--sab));
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 30px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  z-index: 10;
}
.player.hidden { display: none; }
.play {
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--accent); color: var(--accent-text);
  display: grid; place-items: center; flex: none; border: 0; cursor: pointer;
}
/* Полоса перемотки остаётся тонкой, а попадать в неё надо пальцем: область
   нажатия растягивает прозрачный ::after, сама полоса не толстеет. */
.player .track { flex: 1; height: 4px; background: var(--ground-deep); border-radius: 2px; cursor: pointer; position: relative; }
.player .track::after { content: ""; position: absolute; inset: -16px 0; }
.player .track i { display: block; width: 0; height: 100%; background: var(--accent); border-radius: 2px; }
.player .time { font-size: 12px; color: var(--hint); font-variant-numeric: tabular-nums; }

/* ── Кнопки и модальные окна ──────────────────────────────────────────── */

.fab {
  position: fixed;
  right: 16px;
  bottom: calc(16px + var(--sab));
  height: 54px;
  padding: 0 22px;
  border-radius: 27px;
  border: 0;
  background: var(--accent);
  color: var(--accent-text);
  font-size: 15.5px;
  font-weight: 600;
  box-shadow: var(--shadow-lg);
  cursor: pointer;
  z-index: 20;
}
.fab:active { transform: scale(.97); }
/* На конспекте — круглый «плюс» в правом верхнем углу под шапкой: внизу
   стоит панель доски, слева на ноутбуке — её же столбик, а сверху справа
   свободно на любом экране. Большой и заметный — так просил владелец. */
.fab.fab-round {
  width: 56px; height: 56px; padding: 0;
  border-radius: 50%;
  font-size: 30px; font-weight: 500; line-height: 1;
  display: grid; place-items: center;
  top: calc(64px + var(--sat, 0px)); bottom: auto; right: 14px;
}

.sheet-modal {
  position: fixed;
  inset: 0;
  background: rgba(8, 10, 14, .5);
  backdrop-filter: blur(3px);
  display: none;
  align-items: flex-end;
  z-index: 40;
}
.sheet-modal.open { display: flex; }
.sheet-modal .panel {
  background: var(--ground);
  width: 100%;
  border-radius: 22px 22px 0 0;
  padding: 22px 18px calc(22px + var(--sab));
  max-height: 88vh;
  overflow-y: auto;
}
.sheet-modal h3 { margin: 0 0 16px; font-size: 18px; font-family: var(--serif); }

.row-btn {
  display: flex;
  align-items: center;
  gap: 13px;
  width: 100%;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--card);
  font-size: 15px;
  text-align: left;
  margin-bottom: 10px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.row-btn:active { transform: scale(.99); }
.row-btn .ic { font-size: 20px; width: 26px; text-align: center; flex: none; }
.row-btn small { display: block; color: var(--hint); font-size: 12.5px; margin-top: 3px; }

.field {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 13px 14px;
  font-size: 15px;
  background: var(--card);
  color: var(--text);
  margin-bottom: 12px;
}
.field:focus { border-color: var(--accent); outline: none; }

.colors { display: flex; gap: 9px; flex-wrap: wrap; margin-bottom: 16px; }
.colors button {
  width: 38px; height: 38px; border-radius: 10px;
  border: 2px solid var(--line);
  background: var(--card);
  cursor: pointer;
  font-size: 18px;
}
.colors button[aria-pressed="true"] { border-color: var(--accent); }

.primary {
  width: 100%;
  padding: 15px;
  border: 0;
  border-radius: 13px;
  background: var(--accent);
  color: var(--accent-text);
  font-size: 15.5px;
  font-weight: 600;
  cursor: pointer;
}
.primary[disabled] { opacity: .5; }
.primary:active { transform: scale(.985); }
.primary { transition: transform .12s ease, filter .15s ease; }
@media (hover: hover) and (pointer: fine) {
  .primary:hover { filter: brightness(1.06); }
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(84px + var(--sab));
  transform: translateX(-50%);
  background: rgba(16, 18, 24, .95);
  color: #fff;
  padding: 10px 17px;
  border-radius: 20px;
  font-size: 13.5px;
  max-width: 84vw;
  z-index: 60;
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s;
}
.toast.show { opacity: 1; }

.skeleton {
  background: linear-gradient(90deg, var(--ground-deep) 25%, var(--card) 37%, var(--ground-deep) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease infinite;
  border-radius: 8px;
}
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* Линовка — экранная фактура. На бумаге и в PDF её быть не должно. */
@media print {
  .sheet { background-image: none; }
  .sheet::after { display: none; }
}

/* ── Блоки конспекта ───────────────────────────────────────────────────
   Определение, формула и экзаменационное выглядят по-разному, потому что
   и читаются по-разному: определение ищут глазами, формулу переписывают,
   экзаменационное перечитывают перед сдачей. */

.tldr {
  font-size: 15.5px;
  line-height: 1.62;
  padding: 14px 16px;
  background: var(--accent-soft);
  border-radius: 11px;
  margin-bottom: 22px;
}
.tldr b {
  font-family: var(--sans);
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent);
  display: block;
  margin-bottom: 6px;
  font-weight: 700;
}

.block { margin-bottom: 20px; }
.block-label {
  font-family: var(--sans);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--paper-label);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin-bottom: 7px;
}
.block-body p { margin: 0 0 8px; }
.block-body ul { margin: 5px 0 8px; padding-left: 21px; }

.type-definition, .type-theorem {
  border-left: 3px solid var(--accent);
  padding-left: 13px;
}
.type-exception, .type-distinction {
  border-left: 3px solid var(--hint);
  padding-left: 13px;
}

.formula {
  font-size: 16px;
  text-align: center;
  padding: 14px 14px;
  background: var(--chip-paper);
  border-radius: 12px;
  margin: 9px 0;
  overflow-x: auto;
  line-height: 1.7;
}
.math { font-style: italic; }

.is-exam {
  background: var(--exam);
  border: 1px solid var(--exam-line);
  border-radius: 11px;
  padding: 13px 15px 9px 34px;
  position: relative;
  margin-left: -4px;
}
.is-exam::before {
  content: "⚑";
  position: absolute;
  left: 12px; top: 12px;
  color: var(--exam-text);
  font-size: 14px;
}
.is-exam .block-label { color: var(--exam-text); }
.is-check { border-left: 3px dotted var(--exam-line); padding-left: 13px; }

.quote-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 32px;
  background: var(--chip-paper);
  border: 0;
  color: var(--paper-label);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 3px 9px 3px 7px;
  border-radius: 8px;
  line-height: 1.3;
  vertical-align: middle;
  transition: transform .12s ease, color .15s ease;
}
.quote-btn::before {
  content: "";
  width: 11px; height: 11px;
  flex: none;
  background: currentColor;
  -webkit-mask: var(--ic-quote) center / 11px 11px no-repeat;
  mask: var(--ic-quote) center / 11px 11px no-repeat;
}
.quote-btn:active { color: var(--accent); transform: scale(.94); }

.exam-block {
  border: 1px solid var(--exam-line);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 20px;
  background: var(--exam);
}
.exam-block .block-label { color: var(--exam-text); }
.exam-block ul { margin: 0; padding-left: 19px; }
.exam-block li { font-size: 15px; line-height: 1.55; margin-bottom: 6px; }

.aside {
  font-family: var(--sans);
  border-top: 1px solid var(--rule);
  padding-top: 16px;
  margin-top: 24px;
}
.aside h3 {
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--paper-label);
  margin: 0 0 9px;
  font-weight: 700;
}
.aside ul { margin: 0 0 18px; padding-left: 18px; }
.aside li { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); margin-bottom: 5px; }
.terms { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 18px; }
.term {
  font-size: 12px;
  padding: 5px 10px;
  border-radius: 8px;
  background: var(--chip-paper);
  color: var(--ink-soft);
}

/* ══════════════════════════════════════════════════════════════════════════
   ИКОНКИ

   Системные эмодзи в интерфейсе выглядят дёшево: они цветные, разного веса
   и на каждой платформе свои. Здесь тот же почерк, что у SVG в разметке —
   обводка 2, скруглённые концы, цвет берётся из currentColor через маску.
   Так одна кнопка не может «покраситься» мимо темы. */

:root {
  --ic-play:   url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M8 5.5v13l11-6.5z'/></svg>");
  --ic-quote:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M10 5.5v6.2c0 3.4-2 5.6-5 6.8v-2.6c1.6-.8 2.5-2 2.6-3.4H5V5.5zM21 5.5v6.2c0 3.4-2 5.6-5 6.8v-2.6c1.6-.8 2.5-2 2.6-3.4H16V5.5z'/></svg>");
  --ic-up:     url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 19V6'/><path d='M6 12l6-6 6 6'/></svg>");
  --ic-down:   url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 5v13'/><path d='M18 12l-6 6-6-6'/></svg>");
  --ic-flag:   url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 21V4'/><path d='M5 4.5h12l-2.4 4 2.4 4H5z'/></svg>");
  --ic-sigma:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 5H6.5l6 7-6 7H18'/></svg>");
  --ic-camera: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 8.5h3l1.6-2.5h8.8L18 8.5h3v11H3z'/><circle cx='12' cy='13.5' r='3.4'/></svg>");
  --ic-plus:   url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'><path d='M12 5v14'/><path d='M5 12h14'/></svg>");
  --ic-trash:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 7h16'/><path d='M9.5 7V4h5v3'/><path d='M6.5 7l1 13h9l1-13'/></svg>");
  --ic-pencil: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 20h4L20 8l-4-4L4 16z'/><path d='M14.5 5.5l4 4'/></svg>");
  --ic-check:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12.5l4.5 4.5L19 7'/></svg>");
  --ic-cloud:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M7 18a4 4 0 0 1-.4-8 5.5 5.5 0 0 1 10.6 1.2A3.6 3.6 0 0 1 17.5 18z'/></svg>");
  --ic-alert:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9'/><path d='M12 7.5v6'/><path d='M12 16.6h.01'/></svg>");
  --ic-eye:    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12z'/><circle cx='12' cy='12' r='3'/></svg>");
  --ic-zoom:   url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='11' cy='11' r='6.5'/><path d='M20.5 20.5L16 16'/><path d='M11 8.5v5'/><path d='M8.5 11h5'/></svg>");
  --ic-close:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'><path d='M6 6l12 12'/><path d='M18 6L6 18'/></svg>");
  --ic-spark:  url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='black'><path d='M12 2l1.9 6.4L20 10l-6.1 1.6L12 18l-1.9-6.4L4 10l6.1-1.6z'/></svg>");
}

/* Общий приём: пустая кнопка + маска в ::before. font-size:0 гасит эмодзи
   или символ, который остался в разметке от предыдущего слоя. */
.ic-mask::before {
  content: "";
  display: block;
  background: currentColor;
  -webkit-mask: var(--ic) center / 100% 100% no-repeat;
  mask: var(--ic) center / 100% 100% no-repeat;
}

/* ══════════════════════════════════════════════════════════════════════════
   ПОЛКА: ПЕРВЫЙ ЗАПУСК

   У новичка на экране три двери и подаренный пример. Заголовок зовёт, а не
   извиняется за пустоту, и между примером и дверями нет провала. */

/* Плавающая кнопка накрывала последнюю книгу и последнюю лекцию. */
#screen-shelf, #screen-subject { padding-bottom: calc(88px + var(--sab)); }

/* Когда на экране уже стоят три двери, плавающая кнопка «Записать лекцию» —
   четвёртый способ сделать то же самое. Убираем, чтобы выбор был из трёх. */
body:has(#shelf-empty:not([hidden])) .fab { display: none; }

#shelf-empty { padding-top: 8px; }

.starters {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 18px 0 4px;
  text-align: left;
}

/* Дверь на первом запуске: крупная цель, иконка в тёплой плашке, стрелка
   справа — чтобы читалось «сюда ведёт», а не «тут написано». */
.starters .row-btn.starter {
  align-items: center;
  min-height: 68px;
  gap: 14px;
  padding: 13px 44px 13px 13px;
  margin: 0;
  position: relative;
  border-radius: 15px;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--card) 100%, transparent), var(--card));
  box-shadow: var(--shadow-sm), inset 0 1px 0 rgba(255, 255, 255, .55);
  transition: transform .14s ease, box-shadow .2s ease;
}
html.dark .starters .row-btn.starter { box-shadow: var(--shadow-sm); }
.starters .row-btn.starter:active { transform: scale(.985); box-shadow: var(--shadow-sm); }
@media (hover: hover) and (pointer: fine) {
  .starters .row-btn.starter:hover { box-shadow: var(--shadow-md); }
}

.starter .ic {
  width: 42px; height: 42px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 19px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent);
}
.starter > span:last-child { display: block; font-size: 15.5px; font-weight: 650; line-height: 1.25; }
.starter small { color: var(--text-soft); font-weight: 400; font-size: 12.5px; line-height: 1.35; margin-top: 3px; }
/* Стрелка «дальше»: рисуется, а не набирается символом. */
.starter::after {
  content: "";
  position: absolute;
  right: 15px; top: 50%;
  width: 16px; height: 16px;
  margin-top: -8px;
  background: var(--hint);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M9 5l7 7-7 7'/></svg>") center / 100% 100% no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='M9 5l7 7-7 7'/></svg>") center / 100% 100% no-repeat;
}

/* Подаренный пример. Отличается от своих конспектов рамкой-пунктиром и
   значком: «это не твоё, это показать». */
.revise-tile.sample-tile {
  background: linear-gradient(135deg, var(--accent-soft), color-mix(in srgb, var(--card) 82%, var(--accent-soft)));
  border: 1px dashed color-mix(in srgb, var(--accent) 42%, transparent);
  box-shadow: none;
  margin-bottom: 14px;
  padding-right: 8px;
}
.revise-tile.sample-tile::before { background: none; }
.sample-tile .revise-ic {
  width: 34px; height: 34px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
  font-size: 15px;
}
.sample-tile .revise-text b { color: var(--text); }
.sample-tile .revise-text small { color: var(--accent); opacity: .95; }

/* «Убрать пример» — 36 px кнопка с полем нажатия до 44 px, а не крестик 17 px. */
.sample-drop {
  margin-left: auto;
  flex: none;
  width: 36px; height: 36px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  color: var(--hint);
  font-size: 0;
  position: relative;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.sample-drop::before {
  content: "";
  width: 14px; height: 14px;
  background: currentColor;
  -webkit-mask: var(--ic-close) center / 100% 100% no-repeat;
  mask: var(--ic-close) center / 100% 100% no-repeat;
}
.sample-drop::after { content: ""; position: absolute; inset: -4px; }
.sample-drop:active { background: var(--chip); color: var(--text); }
@media (hover: hover) and (pointer: fine) {
  .sample-drop:hover { background: var(--chip); color: var(--text); }
}

/* Кнопка в пустом состоянии: не во всю ширину — так она читается как
   предложение, а не как единственный выход. */
.empty-cta {
  margin: 16px auto 0;
  max-width: 260px;
  width: auto;
  min-width: 180px;
  padding: 14px 22px;
}

/* ══════════════════════════════════════════════════════════════════════════
   ЛИСТ: ПОДАРЕННЫЙ ПРИМЕР, ВЫДЕЛЕНИЯ, ЦИТАТЫ */

/* Ленточка «это пример» вверху листа. */
.sample-note {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin: 0 0 16px;
  padding: 10px 13px;
  border-radius: 11px;
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--sans);
  font-size: 12.5px;
  line-height: 1.45;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
}
.sample-note::before {
  content: "";
  flex: none;
  width: 15px; height: 15px;
  margin-top: 1px;
  background: currentColor;
  -webkit-mask: var(--ic-spark) center / 100% 100% no-repeat;
  mask: var(--ic-spark) center / 100% 100% no-repeat;
}

/* Оба класса генерирует разметчик конспекта, и до сих пор их не рисовало
   ничто: выделение приезжало обычным текстом, цитата — обычным абзацем. */
.sheet .hl {
  background: linear-gradient(180deg, transparent 42%, var(--exam) 42%);
  color: inherit;
  padding: 0 2px;
  border-radius: 2px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
html.dark .sheet .hl { background: linear-gradient(180deg, transparent 42%, rgba(233, 196, 106, .26) 42%); }
.sheet blockquote {
  margin: 12px 0;
  padding: 2px 0 2px 15px;
  border-left: 3px solid var(--rule);
  color: var(--ink-soft);
  font-style: italic;
}
.sheet blockquote p:last-child { margin-bottom: 0; }

/* Тень у края выключной формулы живёт в math.css — она сделана там правильно,
   парой заплаток (бумага + тонировка блока), и дублировать её отсюда более
   сильным селектором значило бы сломать чужую механику. Единственное, что
   лист просит от неё, — ручка пошире: на бумаге в линейку узкая полоска
   теряется среди линовки. Ширина вынесена у соседа в свою переменную, ею и
   пользуемся. */
.sheet .math-block { --math-edge: 24px; }

/* Заплатка прокрутки берёт под собой бумагу и красит её сверху цветом блока.
   В светлом оформлении жёлтый непрозрачен, и там, где оба слоя гаснут, из-под
   них проступает бумага — поперёк формулы ложится бледная полоса. Основанием
   должен быть цвет самого блока: тогда любое смешение слоёв даёт его же.
   В тёмном оформлении жёлтый полупрозрачный, и бумага под ним как раз верна —
   там оставляем как есть. Переменные соседские, они для этого и заведены. */
.sheet .is-exam .math-block,
.sheet .exam-block .math-block { --math-base: var(--exam); }
.sheet .tldr .math-block { --math-base: var(--accent-soft); }
html.dark .sheet .is-exam .math-block,
html.dark .sheet .exam-block .math-block,
html.dark .sheet .tldr .math-block { --math-base: var(--paper); }

/* ══════════════════════════════════════════════════════════════════════════
   СНИМОК ДОСКИ НА ЛИСТЕ

   Снимок лежит на бумаге как вклеенная фотография: белое паспарту, тонкая
   рамка, подпись под ней тем же почерком, что и остальные служебные надписи
   листа. */

img { max-width: 100%; height: auto; }

.sheet-photo {
  margin: 14px 0 16px;
  padding: 0;
}
.sheet-photo img {
  display: block;
  width: 100%;
  border-radius: 8px;
  cursor: zoom-in;
  background: var(--chip-paper);
  box-shadow:
    0 0 0 1px var(--rule),
    0 1px 2px rgba(20, 24, 34, .10),
    0 10px 22px -14px rgba(20, 24, 34, .55);
  transition: transform .16s ease;
}
.sheet-photo img:active { transform: scale(.99); }
.sheet-photo figcaption {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--paper-label);
}
.sheet-photo figcaption::before {
  content: "";
  flex: none;
  width: 13px; height: 13px;
  background: currentColor;
  -webkit-mask: var(--ic-camera) center / 100% 100% no-repeat;
  mask: var(--ic-camera) center / 100% 100% no-repeat;
  opacity: .75;
}
/* Блок-снимок не нуждается в левой линейке типа: картинка сама себе граница. */
.type-photo { border-left: 0; padding-left: 0; }
.type-raw .block-body > :first-child { margin-top: 0; }

/* Снимок во весь экран. */
.photo-view {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: calc(20px + var(--sat)) 12px calc(84px + var(--sab));
  background: rgba(8, 10, 14, .93);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  animation: photo-in .18s ease;
}
@keyframes photo-in { from { opacity: 0 } to { opacity: 1 } }
.photo-view[hidden] { display: none; }
.photo-view-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .9);
}
.photo-view-bar {
  position: absolute; left: 0; right: 0; bottom: calc(18px + var(--sab));
  display: flex; justify-content: center; gap: 10px; color: #fff;
}
.photo-view-bar .tool-btn {
  width: auto; min-width: 44px; height: 44px; padding: 0 20px;
  border-radius: 22px;
  background: rgba(255, 255, 255, .13);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
  color: #fff;
  font-size: 14.5px; font-weight: 600;
  transition: background .15s ease, transform .12s ease;
}
.photo-view-bar .tool-btn:active { background: rgba(255, 255, 255, .24); transform: scale(.97); }
.photo-view-bar .tool-btn.danger { color: #FCA5A5; background: rgba(220, 38, 38, .18); box-shadow: inset 0 0 0 1px rgba(252, 165, 165, .32); }
.photo-view-bar .tool-btn.danger:active { background: rgba(220, 38, 38, .32); }

/* ══════════════════════════════════════════════════════════════════════════
   ПРАВКА КОНСПЕКТА ПО АБЗАЦАМ

   Правило одно: пока абзац закрыт, лист остаётся листом. Ручка тихая,
   действия появляются только у открытого абзаца — и одной полосой, а не
   калькулятором на семь клавиш. */

/* Лист в режиме правки: тёплая рамка по краю бумаги — видно, что она «живая»,
   но текст не перекрашивается и не прыгает. */
.sheet.editing {
  box-shadow: var(--shadow-lg), 0 0 0 2px color-mix(in srgb, var(--accent) 34%, transparent);
}

.block.editable { cursor: text; border-radius: 8px; position: relative; }
/* Ручка стоит в углу абзаца — метке надо оставить под неё место. Заголовку
   не надо: он начинается ниже строки метки. */
.block.editable > .block-label { padding-right: 38px; }
.block.editable.is-exam > .block-handle { top: 6px; right: 6px; }
/* В режиме правки «цитата» уходит: это действие чтения (послушать, как это
   было сказано), а строку метки оно перебивает на вторую — вместе с ручкой
   они в 318 px не встают. Вернётся, как только нажмут «Готово». */
.sheet.editing .block.editable .quote-btn { display: none; }
.block.editable:active { background: var(--chip-paper); }
@media (hover: hover) and (pointer: fine) {
  .block.editable:hover { background: var(--chip-paper); }
  .block.editable:hover .block-handle { opacity: 1; }
}

/* Ручка «поправить абзац»: 34 px кружок, поле нажатия 44. */
.block-handle {
  position: absolute;
  top: -2px; right: -4px;
  z-index: 2;
  width: 34px; height: 34px;
  margin: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--chip-paper);
  color: var(--paper-label);
  font-size: 0;
  line-height: 1;
  cursor: pointer;
  opacity: .62;
  transition: opacity .15s ease, background .15s ease, color .15s ease;
}
.block-handle::before {
  content: "";
  width: 16px; height: 16px;
  background: currentColor;
  -webkit-mask: var(--ic-pencil) center / 100% 100% no-repeat;
  mask: var(--ic-pencil) center / 100% 100% no-repeat;
}
.block-handle::after { content: ""; position: absolute; inset: -5px; }
.block-handle:active { opacity: 1; background: var(--accent-soft); color: var(--accent); }

/* Открытый абзац: карточка на бумаге. Отступы перебивают левые линейки
   типов (.type-definition и прочие), поэтому селектор сильнее. */
.sheet .block.editing {
  background: var(--paper-tint);
  border: 0;
  border-radius: 14px;
  padding: 13px 13px 11px;
  margin: 14px -13px 18px;
  box-shadow: inset 0 0 0 1px var(--rule), 0 10px 26px -18px rgba(20, 24, 34, .6);
}
.sheet .block.editing .block-label {
  color: var(--accent);
  margin-bottom: 9px;
  min-height: 0;
}

/* Заголовок абзаца — не поле ввода в интерфейсе, а строка на бумаге. */
.sheet .block-title {
  margin: 0 0 9px;
  padding: 8px 12px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 700;
  line-height: 1.3;
}
.sheet .block-title::placeholder { color: var(--paper-label); font-weight: 400; opacity: .8; }
.sheet .block-title:focus { border-color: color-mix(in srgb, var(--accent) 55%, transparent); outline: none; }

/* Поле правки: та же бумага, тот же шрифт, тот же интерлиньяж, что у текста
   абзаца — человек правит конспект, а не «редактирует запись». */
.block-edit {
  display: block;
  width: 100%;
  box-sizing: border-box;
  resize: vertical;
  min-height: 76px;
  padding: 11px 13px;
  border: 1px solid var(--rule);
  border-radius: 11px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.62;
  box-shadow: inset 0 1px 2px rgba(20, 24, 34, .04);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.block-edit:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}
.block-edit::placeholder { color: var(--paper-label); opacity: .75; }

/* Предпросмотр. Он нужен ровно там, где человек не понимает, что набрал, —
   то есть в формулах. В обычном абзаце «как это будет выглядеть» повторяло
   поле слово в слово и занимало столько же места; там его теперь нет.
   :not(:has(…)) выбран сознательно: на движке без :has правило целиком
   недействительно, и предпросмотр останется видимым — это хуже по виду,
   но не отнимает функцию. */
.block-preview-label {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 13px 0 -9px 13px;
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--paper-tint);
  font-family: var(--sans);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--paper-label);
}
.block-preview-label::before {
  content: "";
  width: 12px; height: 12px;
  background: currentColor;
  -webkit-mask: var(--ic-eye) center / 100% 100% no-repeat;
  mask: var(--ic-eye) center / 100% 100% no-repeat;
}
.block-preview {
  padding: 12px 13px 4px;
  border: 1px dashed var(--rule);
  border-radius: 11px;
  background: var(--paper);
  color: var(--ink);
  font-size: .9em;
  opacity: 1;
}
.block-preview > :last-child { margin-bottom: 6px; }
.block-preview:not(:has(.katex, .math-block, .math-raw, .math-error, .sheet-photo)) { display: none; }
.block-preview-label:not(:has(
  + .block-preview .katex, + .block-preview .math-block,
  + .block-preview .math-raw, + .block-preview .math-error,
  + .block-preview .sheet-photo)) { display: none; }

/* Действия над абзацем — одна полоса иконок, а не сетка кнопок. Порядок
   тот же, что в разметке: подвинуть, пометить, вставить, добавить. «Удалить»
   отбито чертой и красное: промах по нему стоит дороже всех. */
.block-acts {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  width: fit-content;
  max-width: 100%;
  gap: 2px;
  margin-top: 12px;
  padding: 4px;
  border-radius: 13px;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--rule), var(--shadow-sm);
}
.block-act {
  flex: none;
  width: 38px; height: 38px;
  min-width: 0; min-height: 0;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink-soft);
  font-size: 0;
  cursor: pointer;
  position: relative;
  transition: background .15s ease, color .15s ease, transform .12s ease;
}
.block-act::before {
  content: "";
  width: 19px; height: 19px;
  background: currentColor;
  -webkit-mask: var(--ic) center / 100% 100% no-repeat;
  mask: var(--ic) center / 100% 100% no-repeat;
}
/* Поле нажатия 48 px при кнопке 38 — палец попадает, полоса не раздувается. */
.block-act::after { content: ""; position: absolute; inset: -5px; }
.block-act:active { transform: scale(.9); background: var(--chip-paper); }
.block-act.on { background: var(--accent-soft); color: var(--accent); }
@media (hover: hover) and (pointer: fine) {
  .block-act:hover { background: var(--chip-paper); color: var(--ink); }
  .block-act.on:hover { background: var(--accent-soft); color: var(--accent); }
}
.block-act[data-bact="up"]      { --ic: var(--ic-up); }
.block-act[data-bact="down"]    { --ic: var(--ic-down); }
.block-act[data-bact="exam"]    { --ic: var(--ic-flag); }
.block-act[data-bact="formula"] { --ic: var(--ic-sigma); }
.block-act[data-bact="photo"]   { --ic: var(--ic-camera); }
.block-act[data-bact="add"]     { --ic: var(--ic-plus); }
.block-act[data-bact="del"] {
  --ic: var(--ic-trash);
  color: var(--danger);
  margin-left: 6px;
  padding-left: 6px;
  width: 45px;
  border-left: 1px solid var(--rule);
}
.block-act[data-bact="del"]:active { background: color-mix(in srgb, var(--danger) 13%, transparent); }
@media (hover: hover) and (pointer: fine) {
  .block-act[data-bact="del"]:hover { background: color-mix(in srgb, var(--danger) 11%, transparent); color: var(--danger); }
}
.block-act[data-bact="exam"].on { background: var(--exam); color: var(--exam-text); }

/* «Добавить блок» — пунктирная строка на бумаге: место, куда ляжет новый
   абзац, а не ещё одна кнопка интерфейса. */
.block-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 46px;
  margin: 16px 0 8px;
  padding: 0 14px;
  border: 1px dashed color-mix(in srgb, var(--paper-label) 45%, transparent);
  border-radius: 12px;
  background: transparent;
  color: var(--paper-label);
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s ease, color .15s ease, background .15s ease, transform .12s ease;
}
.block-add:active { transform: scale(.99); background: var(--chip-paper); color: var(--accent); border-color: var(--accent); }
@media (hover: hover) and (pointer: fine) {
  .block-add:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
}

/* Заголовок конспекта и «суть за 30 секунд» правятся там же, где стоят. */
.meta-edit { cursor: text; border-radius: 8px; }
.meta-edit:active { background: var(--chip-paper); }
@media (hover: hover) and (pointer: fine) {
  h1.meta-edit:hover { background: var(--chip-paper); }
}
h1.meta-edit { box-shadow: 0 1px 0 var(--rule); }
.meta-input { margin: 0; }
input.meta-input {
  padding: 6px 10px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 25px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.018em;
}
input.meta-input:focus { border-color: color-mix(in srgb, var(--accent) 55%, transparent); outline: none; }
textarea.meta-input { margin-top: 6px; min-height: 62px; background: color-mix(in srgb, var(--paper) 70%, transparent); }
.hint-line { color: var(--paper-label); font-style: italic; opacity: .9; }

/* ══════════════════════════════════════════════════════════════════════════
   ЧТО С ПРАВКАМИ: ПЛАШКА СОСТОЯНИЯ */

.save-badge {
  margin-left: auto;
  border: 0;
  cursor: default;
  gap: 6px;
  min-height: 28px;
  padding: 4px 10px;
  font-size: 11.5px;
  font-weight: 600;
  background: var(--chip);
  color: var(--text-soft);
  transition: background .2s ease, color .2s ease;
}
.save-badge::before {
  content: "";
  flex: none;
  width: 12px; height: 12px;
  background: currentColor;
  -webkit-mask: var(--ic-check) center / 100% 100% no-repeat;
  mask: var(--ic-check) center / 100% 100% no-repeat;
}
.save-badge.is-ok { background: var(--chip); color: var(--text-soft); }
.save-badge.is-busy { background: var(--accent-soft); color: var(--accent); }
.save-badge.is-busy::before {
  -webkit-mask: none; mask: none;
  border-radius: 50%;
  background: currentColor;
  animation: badge-pulse 1s ease-in-out infinite;
}
@keyframes badge-pulse { 0%, 100% { opacity: .35; transform: scale(.7) } 50% { opacity: 1; transform: scale(1) } }
.save-badge.is-wait { background: var(--exam); color: var(--exam-text); }
.save-badge.is-wait::before { -webkit-mask: var(--ic-cloud) center / 100% 100% no-repeat; mask: var(--ic-cloud) center / 100% 100% no-repeat; width: 14px; height: 14px; }
.save-badge.is-err { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }
.save-badge.is-err::before { -webkit-mask: var(--ic-alert) center / 100% 100% no-repeat; mask: var(--ic-alert) center / 100% 100% no-repeat; width: 13px; height: 13px; }
.note-tools .tools-zoom { margin-left: 8px; }

/* Нижней панели у конспекта больше нет: «…» стоит в шапке, правят двойным
   нажатием, доска идёт до самого низа экрана. Плеер прижат к низу с
   отступом под домашнюю полоску. */
#screen-note.active .player { bottom: calc(12px + var(--sab)); }

/* Плашка «тебя опередили» / «снимок не ушёл»: жёлтая, как всё, что требует
   решения, и с кнопками нормального размера. */
.readonly-note.note-warn {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--exam);
  color: var(--exam-text);
  border-bottom: 1px solid var(--exam-line);
}
/* Текст занимает всю строку, кнопки встают под ним в ряд: иначе «Не надо»
   уезжало на третью строку и плашка вырастала на пол-экрана. */
.note-warn-text { flex: 1 1 100%; font-size: 12.5px; line-height: 1.4; font-weight: 600; }
.note-warn .empty-cta, .note-warn .ghost-btn {
  margin: 0;
  min-height: 38px;
  min-width: 0;
  max-width: none;
  width: auto;
  padding: 0 16px;
  font-size: 13px;
  border-radius: 10px;
}

/* ══════════════════════════════════════════════════════════════════════════
   МЕЛОЧИ ИЗ ОСТАЛЬНЫХ ЭКРАНОВ, ЖИВШИЕ ВО ВРЕМЕННОМ БЛОКЕ */

/* display:flex у плиток перебивал атрибут hidden. */
.revise-tile[hidden], .sample-tile[hidden] { display: none; }

/* Формула внутри кнопки ответа не должна перехватывать нажатие. */
.option-math .katex, .option-math .math-inline { pointer-events: none; }
.option-math .math-block { overflow: visible; }
/* Вердикт с тайм-кодом можно нажать, чтобы листать самому. */
.verdict.tappable { cursor: pointer; }
.verdict.tappable::after {
  content: "нажми, чтобы дальше";
  display: block;
  margin-top: 6px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
  opacity: .7;
}

/* Выбор значка предмета: 44 px цель вместо 38. */
.emoji-pick {
  background: var(--card);
  font-size: 19px;
  width: 44px; height: 44px;
  transition: transform .12s ease, border-color .15s ease;
}
.emoji-pick:active { transform: scale(.94); }

/* ── Ноутбук: кегль листа больше, значит и шаг линовки другой ──────────────
   desktop.css поднимает .sheet p/li до 16.5px и меняет поля — линовка обязана
   считаться от тех же чисел, иначе она разъезжается с текстом. */
@media (min-width: 860px) {
  .sheet { --sheet-fs: 16.5px; --sheet-top: 40px; }
  .sheet h1 { letter-spacing: -.02em; }
  .sheet .block.editing { margin-left: -16px; margin-right: -16px; padding: 16px 16px 13px; }
  .starters { max-width: 520px; margin-inline: auto; }
  .empty-cta { max-width: 300px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   ЛИСТ — СТРАНИЦА ДОКУМЕНТА, А НЕ ХОЛСТ

   Масштаба у листа больше нет. Раньше страница жила на холсте: щипок, кнопки
   «−/100%/+», трансформация. На телефоне это значило, что конспект
   открывается таким, какой достался, и его сначала надо настроить пальцами.
   Теперь ширина фиксирована, прокрутка обычная, кегль сразу читаемый.

   Правила стоят на id: в board.css лист ещё описан как холст, но тот файл
   про доску, и масштаб доски мы не трогаем. */

/* touch-action листу оставляем как есть (pan-x pan-y из board.css): щипок
   он и так не пропускает, а горизонтальная прокрутка нужна широким
   формулам внутри абзаца. */
#board-inner { width: auto; height: auto; }
#sheet-wrap {
  position: static;
  transform: none;
  width: auto;
  /* Длинная строка читается хуже: на широком экране лист остаётся книжным
     и стоит по центру стола. */
  max-width: 720px;
  margin: 0 auto;
  padding: 14px 12px calc(96px + var(--sab));
}
/* Кегль страницы одинаков везде: подгонять его теперь нечем, значит он
   обязан быть читаемым сразу — и на телефоне тоже. */
.sheet { --sheet-fs: 16.5px; }

/* ══════════════════════════════════════════════════════════════════════════
   ПОИСК И АССИСТЕНТ

   Ассистент переехал из шапки к поиску: спрашивают у него о том же, о чём
   ищут, — по своим конспектам. Место в шапке заняло оформление. */

.search-row {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 20px;
}
.search-row[hidden] { display: none; }
.search-row .search { margin-bottom: 0; }
.ask-side {
  position: relative;
  flex: none;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  color: var(--accent);
  box-shadow: var(--shadow-sm);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: transform .12s ease, background .15s ease;
}
.ask-side[hidden] { display: none; }
.ask-side:active { transform: scale(.95); }
/* Ассистент не входит в бесплатное — жёлтая точка честно об этом говорит. */
.ask-side.locked::after {
  content: "";
  position: absolute;
  right: 3px; bottom: 3px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--exam-line);
  box-shadow: 0 0 0 2px var(--card);
}

/* Шапка полки: слева заголовок, справа оформление и справка. */
.head #head-theme svg, .head #head-help svg { display: block; }

/* «Плюс» внутри предмета стоит в шапке — там же, где на полке. Шапка предмета
   белая, поэтому кнопка на ней не белая, иначе её просто не видно. */
.subject-head .head-add {
  flex: none;
  background: var(--chip);
  box-shadow: none;
  font-size: 21px;
}
.subject-head .head-add[hidden] { display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   СПРАВКА

   Вкладка, а не всплывашка: сюда заходят, когда что-то непонятно, и читают
   спокойно. Набрана тем же шрифтом, что и лист, — это тоже текст, который
   читают, а не интерфейс, по которому тыкают. */

.help {
  padding: calc(16px + var(--sat)) 16px calc(40px + var(--sab));
  max-width: 620px;
  margin: 0 auto;
}
.help .head { margin-bottom: 10px; }
.help h2 {
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 700;
  margin: 26px 0 8px;
  letter-spacing: -.01em;
}
.help p {
  font-size: 15px;
  line-height: 1.6;
  margin: 0 0 10px;
  color: var(--text-soft);
}
.help p b { color: var(--text); font-weight: 700; }
.help-lead { font-size: 15.5px; color: var(--text); }
.help-steps { display: grid; gap: 9px; }
.help-step {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  box-shadow: var(--shadow-sm);
}
.help-step b { display: block; font-size: 14.5px; margin-bottom: 3px; color: var(--text); }
.help-step span { font-size: 13.5px; line-height: 1.5; color: var(--text-soft); }
.help-foot {
  margin-top: 26px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 14px;
}

/* Панель масштаба принадлежит доске. На листе её нет, а display:flex из
   board.css перебивал атрибут hidden — кнопки оставались на экране. */
#tools-zoom[hidden] { display: none !important; }

/* Кнопки шапки стоят парой, вплотную. Раньше .head разводила их
   через justify-content: space-between, и на планшете между оформлением
   и справкой зияло 228 px — они читались как две несвязанные вещи.
   Теперь заголовок слева, пара кнопок прижата вправо и держится вместе. */
@media (max-width: 1024px) {
  .head { justify-content: flex-start; gap: 4px; }
  .head h1 { margin-right: auto; }
}


/* ══════════════════════════════════════════════════════════════════════════
   ВИТРИНА ПРИМЕРОВ

   Два приложения в одном: «Примеры конспектов» — только смотреть, «Мои
   конспекты» — работать. Раньше витрина лежала прямо на полке человека
   вперемешку с его лекциями, и было не понять, где чужой образец, а где
   своё; кнопки при этом были на месте, но отказывали — то есть выглядели
   как поломка.

   Полоса висит на КАЖДОМ экране режима и объясняет ровно две вещи: где ты
   и куда идти, чтобы сделать своё. Из неё же и выход. */

.demo-bar {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  align-items: center;
  margin: 0 0 14px;
  padding: 12px 14px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--accent) 12%, var(--card));
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  color: var(--text);
}
.demo-bar[hidden] { display: none; }
.demo-bar b { font-size: 14.5px; grid-column: 1; }
.demo-bar span {
  grid-column: 1;
  font-size: 12.5px; line-height: 1.4; color: var(--text-soft);
}
.demo-out {
  grid-column: 2; grid-row: 1 / span 2;
  border: 0; border-radius: 11px;
  min-height: 42px; padding: 0 16px;
  background: var(--accent); color: var(--accent-text);
  font: 600 13.5px/1 var(--sans); cursor: pointer; white-space: nowrap;
  transition: transform .12s ease, filter .15s ease;
}
.demo-out:active { transform: scale(.97); }
@media (hover: hover) and (pointer: fine) { .demo-out:hover { filter: brightness(1.06); } }
/* Узкий экран: кнопка уезжает под текст, иначе от объяснения остаётся два слова. */
@media (max-width: 420px) {
  .demo-bar { grid-template-columns: 1fr; }
  .demo-out { grid-column: 1; grid-row: auto; margin-top: 6px; }
}

/* Что в витрине не показывается вовсе. Прячем классом на body, а не
   атрибутом hidden у каждой кнопки: hidden этим кнопкам ставит и снимает
   своя логика (тариф, лимиты, поток), и мы бы с ней спорили. */
body.demo #fab,
body.demo #search-row,
body.demo #revise-tile,
body.demo #sample-tile,
body.demo #plan-tile,
body.demo #shelf-empty,
body.demo #subject-add,
body.demo #subject-menu,
body.demo #subject-empty,
body.demo #limit-note,
body.demo #edit-btn,
body.demo #ask-btn,
body.demo #more-btn,
body.demo #note-actions,
body.demo .book-more,
body.demo .add-book { display: none !important; }
