/* style-03-strip-tools.css — часть бывшего style.css (распил 22.10.2026): пустые состояния, треки, шторка телевизора, ряд групп и строка инструментов.
   Файлы style-NN-*.css — ОДИН каскад: index.html подключает их подряд и по номерам, порядок значим
   (правило ниже по каскаду перебивает равное выше). Стережёт tools/check.js. */
  .cell{
    width:64px;height:48px;border-radius:var(--r-md);color:#fff;margin:0 auto;
    display:flex;align-items:center;justify-content:center;font-weight:700;font-size:var(--fs-sm);
  }
  .empty{color:var(--muted);padding:30px 0;text-align:center}

  /* ── ПУСТОЕ СОСТОЯНИЕ (blox51 #12) ──────────────────────────────────────────────
     Класс .empty носил ТРИ РАЗНЫЕ роли одной серой строкой, и это была не мелочь, а
     потеря смысла: «Загрузка…» (сейчас появится содержимое), «Групп пока нет» (содержимого
     нет и вот что с этим делать) и «Не удалось загрузить» (что-то сломалось). Человек
     видел одну и ту же извиняющуюся строчку и не мог отличить ожидание от тупика.
     Роли разведены:
       .empty  — ТОЛЬКО ожидание. Тихая, мелкая, живёт доли секунды и обязана оставаться
                 незаметной: сделать её кадром значило бы получить вспышку на пол-экрана
                 при каждой первой загрузке;
       .estate — НЕЧЕГО ПОКАЗАТЬ. Это не отсутствие экрана, а сам экран: знак, заголовок,
                 одна строка объяснения и — главное — ДЕЙСТВИЕ, которое отсюда выводит.
                 Раньше кнопка «＋ Новая группа» стояла ПОД строкой отдельным блоком, слева,
                 и читалась как не связанная с ней; теперь она часть композиции;
       .efail  — ОТКАЗ. Тот же кадр, но знаком тревоги и её чернилами: «не получилось» не
                 должно выглядеть как «пусто», иначе человек не поймёт, что стоит повторить.
     Кадр — ЛИСТ БУМАГИ (--card + тиснение), а не пунктирная коробка: пунктир в этом
     приложении уже занят и означает «черновик / предстоящий урок» (.opane.empty). */
  .estate{display:flex;flex-direction:column;align-items:center;text-align:center;
    gap:var(--sp-3);padding:var(--sp-8) var(--sp-5);margin:var(--sp-6) auto;max-width:520px;
    background:var(--card);border-radius:var(--r-xl);box-shadow:var(--sheet-1)}
  /* знак в лунке — тот же язык, что у плиток кабинета (.hub-ic), но крупнее и тише:
     это не кнопка, на него не нажимают, он только называет место */
  .estate-ic{display:flex;align-items:center;justify-content:center;width:64px;height:64px;
    border-radius:var(--r-xl);background:var(--surface);color:var(--faint);
    font-size:var(--fs-2xl);line-height:0}
  .estate-t{font-size:var(--fs-xl);font-weight:800;line-height:var(--lh-tight);
    letter-spacing:var(--tracking-tight);color:var(--ink);text-wrap:balance;margin:0}
  /* строка объяснения ограничена по МЕРЕ СТРОКИ, а не по ширине кадра: 42ch — это про
     чтение, а не про раскладку, поэтому на широком экране она не растягивается в ленту */
  .estate-n{font-size:var(--fs-md);color:var(--muted);line-height:var(--lh);max-width:42ch;margin:0}
  /* действие внутри кадра: .toolbar ставит свои отступы и выравнивание по левому краю —
     здесь оно центральное и без верхнего поля, иначе кнопка отваливается от композиции */
  .estate-a{display:flex;flex-wrap:wrap;gap:var(--sp-2);justify-content:center;margin:var(--sp-1) 0 0}
  .efail .estate-ic{background:var(--alert-tint);color:var(--alert)}
  .efail .estate-t{color:var(--alert-ink)}

  /* pool playlist panel */
  /* «Назад» внутри конструктора/расписания = вариант B (контур) на СВЕТЛОМ фоне */
  .back{display:inline-flex;align-items:center;gap:5px;box-sizing:border-box;
        background:none;border:1px solid var(--line);border-radius:var(--r-md);color:var(--muted-strong);
        font-weight:700;font-size:var(--fs-sm);cursor:pointer;padding:7px 13px;margin-bottom:10px;
        transition:border-color var(--t) var(--ease),background var(--t) var(--ease),color var(--t) var(--ease)}
  @media (hover:hover){.back:hover{border-color:var(--accent-deep);background:var(--accent-tint);color:var(--accent-ink)}}
  .now{background:var(--card);border-radius:var(--r-md);padding:16px;
       box-shadow:var(--sheet-2);margin-bottom:16px}
  .now .nt{font-weight:800;font-size:var(--fs-lg);margin-bottom:8px}
  /* blox41 — почему заиграл не тот файл. Спокойный тон: для ребёнка это не его ошибка, поэтому
     не alert-красный, а обычная подпись; строка держится до следующего осознанного тапа. */
  .now .pskip{font-size:var(--fs-sm);color:var(--muted);margin:-4px 0 10px}
  .now .pskip[hidden]{display:none}
  /* blox52 #17: аудио пула играет НАШ плеер (.lp) — лист в лист не кладём: внутри карточки .now
     у него нет своей подложки/тени/полей, он часть карточки (правило `.now audio` ушло вместе с
     системным <audio controls>; видео ставит ширину само, инлайном, как и раньше) */
  .now .lp{box-shadow:none;background:none;padding:0;max-width:none}
  .track{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:var(--r-md);
         background:var(--card);box-shadow:var(--sheet-1);margin-bottom:8px;cursor:pointer}
  .track.playing{outline:2px solid var(--accent-deep)}
  /* битый трек остаётся в списке НАЗЛО соблазну его спрятать: спрятанный файл — это молча отнятый
     у группы файл, а вердикт по кодеку бывает неверным. Виден, помечен, но не преграждает дорогу. */
  .track.broken .tt{color:var(--muted)}
  .track.broken .meta{color:var(--alert)}
  .track.broken .dot{background:var(--muted)!important;border:none!important}
  .dot{width:14px;height:14px;border-radius:50%;flex:0 0 auto;box-sizing:border-box}
  /* лестница точки трека (blox52 #11): не слушал → ПУСТОЕ КОЛЬЦО (место под будущую отметку,
     а не красный крик), прослушано (90% хоть раз) → зелёный диск «сделано». Промежуточной
     ступени нет: частичный прогресс в данных не хранится (см. paint() в student.js). */
  .dot-zero{background:transparent;border:2px solid var(--line-mid)}
  .dot-done{background:var(--ok)}
  .track .tt{font-weight:700;flex:1}
  .track .meta{font-size:var(--fs-xs);color:var(--muted)}
  /* ↓ на каждом треке: 44×44 палец-цель (G5), не запускает плеер (stopPropagation) */
  .track .trackdl{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
                  width:44px;height:44px;border-radius:var(--r-md);color:var(--muted);text-decoration:none}
  @media (hover:hover){.track .trackdl:hover{color:var(--primary);background:var(--bg)}}
  .track .trackdl .ic{width:20px;height:20px}
  /* заголовок пула + кнопки «Скачать песни» (весь аудио-плейлист одним zip) и «На телевизор».
     Обе — ОДИН и тот же предмет: таблетка в шапке пула, поэтому и правило одно на двоих
     (blox62 #1). Второй набор свойств рядом — это ровно та копипаста, из которой вырастает
     «почему эти две кнопки разные». */
  .poolhead{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
  .poolhead h2{margin:0}
  .pool-dlall,.pool-tv{flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;
              font-weight:700;font-size:var(--fs-sm);color:var(--primary);--btn-ink:var(--primary);text-decoration:none;
              background:var(--card);border:1px solid var(--line);border-radius:var(--r-pill);
              padding:9px 15px;cursor:pointer;box-shadow:var(--sh-1);min-height:44px}
  @media (hover:hover){.pool-dlall:hover,.pool-tv:hover{border-color:var(--primary);box-shadow:var(--sh-2)}}
  .pool-dlall .ic,.pool-tv .ic{width:16px;height:16px}

  /* ШТОРКА «Смотреть на телевизоре» (blox62 #1, public/tv-pair.js). Своей геометрии почти нет:
     .sheet уже держит ширину, прокрутку и потолок 90vh. Здесь только то, чего в проекте ещё не
     было, — КРУПНЫЕ ЦИФРЫ КОДА: их переписывают с телефона на пульт, глядя то на экран, то на
     телевизор, поэтому цифра стоит в своей клетке и не сливается с соседней. */
  .tvsheet .tv-step{margin:10px 0 6px;color:var(--muted);font-size:var(--fs-sm)}
  .tvsheet .tv-step b{color:var(--ink)}
  .tvsheet .tv-addr{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .tvsheet .tv-addr code{flex:1 1 auto;font-size:var(--fs-md);font-weight:700;color:var(--ink);
              background:var(--bg);border:1px solid var(--line);border-radius:var(--r-md);
              padding:10px 12px;overflow-wrap:anywhere}
  .tvsheet .tv-addr .btn-ghost{width:auto;flex:0 0 auto;margin-top:0}
  .tvsheet .tv-digits{display:flex;gap:6px}
  .tvsheet .tv-digits span{flex:1 1 0;text-align:center;font-weight:800;font-size:var(--fs-xl);
              letter-spacing:.04em;background:var(--bg);border:1px solid var(--line);
              border-radius:var(--r-md);padding:10px 0}
  .tvsheet .tv-left{margin-top:6px;color:var(--muted);font-size:var(--fs-sm)}
  .tvsheet .tv-dhead{margin:16px 0 6px;font-weight:700}
  .tvsheet .tv-dev{display:flex;align-items:center;justify-content:space-between;gap:10px;
              padding:8px 0;border-top:1px solid var(--line)}
  .tvsheet .tv-dev i{display:block;font-style:normal;color:var(--muted);font-size:var(--fs-sm)}
  .tvsheet .tv-dev .btn-ghost{width:auto;flex:0 0 auto;margin-top:0;min-height:44px}

  /* teacher tabs */
  /* segmented control, iOS-style: a soft track with a filled selected pill.
     ОДИН класс на все переключатели «одно из трёх»: вкладки Chats и панель Аудио/Видео/Микс на
     экране плейлиста (blox55 #14 — она была собрана заново инлайном, с цветами числом, и потому
     не слушалась цветовой схемы). Дорожка во ВСЮ ширину колонки, кнопки делят её поровну
     (flex:1) — так панель совпадает по краям с карточками под ней. */
  .tabs{display:flex;gap:4px;margin-bottom:18px;background:var(--fill-soft);
    border-radius:var(--r-md);padding:4px}
  .tabs button{
    flex:1;min-height:44px;                       /* палец: WCAG 2.5.5 */
    border:none;border-radius:var(--r-sm);padding:9px 18px;font-size:var(--fs-sm);font-weight:700;
    /* --muted на дорожке --fill-soft даёт 4.34:1 — под AA для 14px (axe, 02.09.2026).
       --muted-strong заведён ровно для этого случая: «AA on --fill-soft» (theme.css). */
    background:transparent;color:var(--muted-strong);cursor:pointer;
    transition:background-color var(--dur-state) var(--ease-standard),color var(--dur-state) var(--ease-standard),
      box-shadow var(--dur-state) var(--ease-standard);
  }
  .tabs button:focus-visible{outline:none;box-shadow:var(--ring-inset)}
  @media (hover:hover){.tabs button:hover{color:var(--ink)}}
  /* выбранная вкладка = ЯКОРЬ своей схемы (blox55 #14): не «сделано» и не тревога, а выбор —
     значит акцент схемы, а не зелёный/красный (§11). Радужная кнопка детского чата перекрывает
     это правило ниже (.tab-rainbow) и остаётся радужной в любой схеме. */
  .tabs button.on{background:var(--anchor);color:var(--on-dark);box-shadow:var(--sh-1)}
  /* у панели плейлиста свой ритм: она стоит между подписью и карточкой плеера */
  .pool-tabs{margin:12px 0 6px}

  /* add-file panel */
  /* blox51 #3 (заход 8): БЕЗ РАМКИ. Край плоскости определяется ОДИН раз — либо контрастом к
     тому, что под ней, либо линией. Лист лежит на СТОЛЕ (заход 1), а это 1.32 по контрасту:
     край и так виден, и рамка поверх него — второе объявление того же факта. */
  .panel{background:var(--card);border-radius:var(--r-xl);
         padding:20px;box-shadow:var(--sheet-2);margin-bottom:18px}
  .panel h3{margin:0 0 14px;font-size:var(--fs-lg);font-weight:800;color:var(--ink-strong)}
  .field{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
  .field label{font-size:var(--fs-sm);color:var(--muted);font-weight:700}
  /* 16px, а не --fs-md (15px): ниже шестнадцати Safari на айфоне зумит страницу при фокусе и
     обратно не отматывает (шрам blox11 #3, lingo-ui §3). Правило было закрыто на экранах, но
     МОДАЛКИ его пережили — ночной обходчик впервые дошёл до окна нового таска только в
     blox50 #7 (навигация до него не доводила) и сразу нашёл 15px в «Текст». */
  .field input[type=text],.field input[type=url]{
    border:1px solid var(--line);border-radius:var(--r-sm);padding:11px 13px;font-size:var(--fs-input);
    width:100%;background:var(--card);color:var(--ink);transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease);
  }
  .field input:focus,.field select:focus,.field textarea:focus{
    outline:none;border-color:var(--accent-deep);box-shadow:var(--ring)}
  .field.row{flex-direction:row;align-items:center;gap:8px}
  .field.row label{font-size:var(--fs-md);color:var(--ink)}
  .src-tabs{display:flex;gap:8px;margin-bottom:14px}
  .src-tabs button{flex:1;border:1px solid var(--line);background:var(--card);border-radius:var(--r-sm);
    padding:9px;font-weight:700;font-size:var(--fs-sm);color:var(--muted);cursor:pointer}
  .src-tabs button.on{border-color:var(--accent-deep);color:var(--accent-dark);background:var(--accent-tint)}
  /* «Запись» — дверь в инструмент записи задания (24.09): красный кружок, как у кнопки записи, но
     неподвижный — это вход, а не «идёт запись» */
  .src-tabs .src-dot{display:inline-block;width:12px;height:12px;border-radius:50%;background:currentColor;color:var(--danger);vertical-align:-1px}
  /* PRIMARY = grape fill + white text (10.6:1). The sky is too light to carry white
     text, so it works as accent/selection instead — see theme.css. */
  /* .btn-primary → folded onto the engine's --primary role (see BUTTON ENGINE). */
  .hint{font-size:var(--fs-xs);color:var(--muted);margin-top:-4px}
  .hint.ok{color:var(--green);font-weight:700}    /* «Выбрано: файл» в листе сдачи */
  .msg{font-size:var(--fs-md);font-weight:600;margin-top:10px}
  .msg.ok{color:var(--green)} .msg.err{color:var(--red)}
  /* blox52 #18 — слот ошибки ЗАПОЛНЕНИЯ формы (core.js formError). Держит высоту строки
     ПУСТЫМ: текст появляется в уже занятом месте, и кнопка под ним не уезжает из-под пальца
     (то же «нет прыжка», что у .upbar выше). Мельче .msg — это подпись к полю, не итог формы.
     Резерв считается ОТ СОБСТВЕННОГО кегля (1.25em при line-height:1.25 = ровно один строчный
     бокс), а не круглым числом пикселей: круглое число не совпадает с настоящей высотой строки,
     и панель всё равно подрастает — пробник tools/probes/blox52-fslot-jump.js это и намерил. */
  .fslot{min-height:1.25em;line-height:1.25;margin-top:4px;font-size:var(--fs-sm)}
  /* blox51 #1 — полоса отдачи файла в шторке сдачи (живёт внутри .msg, той же высоты, что строка
     текста, — контейнер не прыгает при смене «полоса → текст ошибки») */
  .upbar{height:8px;border-radius:var(--r-2xs);background:var(--line);overflow:hidden;margin:5px 0}
  .upbar i{display:block;height:100%;border-radius:var(--r-2xs);background:var(--anchor);transition:width var(--dur-state)}

  /* file library list */
  .file{display:flex;align-items:center;gap:12px;padding:12px;border-radius:var(--r-md);
        background:var(--card);box-shadow:var(--sheet-1);margin-bottom:8px}
  .file .ico{font-size:var(--ic-lg)}
  .file .info{flex:1;min-width:0}
  .file .info .ft{font-weight:700}
  .file .info .fm{font-size:var(--fs-xs);color:var(--muted)}
  .pill{font-size:var(--fs-2xs);font-weight:700;padding:3px 8px;border-radius:var(--r-lg);
        background:var(--accent-tint);color:var(--accent-dark)}
  .file .act{background:none;border:none;cursor:pointer;font-size:var(--fs-sm);font-weight:700;
        color:var(--accent-dark);padding:6px}
  .file .act.del{color:var(--red)}

  /* teacher home = the group screen. The old list-of-groups monitor is gone: every group of the
     teacher lives in ONE horizontal strip at the top, where the group's title used to be. A chip
     carries ONE indicator when the group needs something: the to-check counter, else a dot. */
  /* position:relative — якорь живого подчёркивания .gind (blox52 #12): индикатор лежит ВНУТРИ
     прокручиваемого ряда, поэтому горизонтальный скролл везёт его вместе с чипами без пересчёта.
     .gs-gswitch — близнец: тот же ряд .gchip на «Уроках» расписания (group-schedule.js), ему
     нужен только якорь — раскладка у него своя и тут не трогается. */
  .gstrip{position:relative;display:flex;gap:8px;overflow-x:auto;padding:2px 2px 8px;margin-bottom:2px;
    -webkit-overflow-scrolling:touch;scrollbar-width:none}
  /* КРАЙ ГОВОРИТ, ЧТО ТАМ ЕЩЁ ЕСТЬ. Полоса прокрутки спрятана, и без намёка спрятанные таблетки
     не существуют для учителя. Рецепт самонастраивающийся, без единой строчки JS: две «шторки»
     цвета листа приклеены к СОДЕРЖИМОМУ (background-attachment:local) и уезжают вместе с ним,
     а две тени приклеены к РАМКЕ (scroll) и стоят на месте — поэтому тень видна ровно с той
     стороны, где что-то спрятано, и гаснет, когда доехали до края. Тон тени — общий --sh-rgb,
     значит намёк следует за цветовой схемой сам. */
  /* ЦВЕТ ШТОРКИ ЗАВИСИТ ОТ ТОГО, НА ЧЁМ ЛЕЖИТ РЯД, и это не мелочь: за лентой групп на мониторе
     стоит ФОН СТРАНИЦЫ (замер 15.09.2026: body.teacher = #d6e2ea), а за полосой уроков — белый
     лист окна. Зашей я сюда --card, монитор получил бы два белых мазка по краям — тот самый
     близнецовый баг, когда правку видят на одном экране и не видят на другом. Поэтому контекст
     САМ объявляет, что у него за спиной; появится третье место — объявит своё. */
  .gstrip{--strip-bg:var(--bg)}
  .emodal .gstrip{--strip-bg:var(--card)}
  .gstrip{
    background:
      linear-gradient(90deg, var(--strip-bg) 40%, transparent) left center,
      linear-gradient(90deg, transparent, var(--strip-bg) 60%) right center,
      radial-gradient(farthest-side at 0 50%, rgba(var(--sh-rgb),.20), transparent) left center,
      radial-gradient(farthest-side at 100% 50%, rgba(var(--sh-rgb),.20), transparent) right center;
    background-repeat:no-repeat;
    background-size:28px 100%, 28px 100%, 12px 100%, 12px 100%;
    background-attachment:local, local, scroll, scroll}
  .gs-gswitch{position:relative}
  .gstrip::-webkit-scrollbar{display:none}
  .gchip{position:relative;flex:0 0 auto;display:flex;align-items:center;gap:7px;cursor:pointer;
    padding:9px 14px;border-radius:var(--r-pill);border:1px solid var(--line);background:var(--card);
    font-weight:800;font-size:var(--fs-md);color:var(--muted);white-space:nowrap;box-shadow:var(--sh-1);
    /* redesign 27.10 — у чипа переходов не было вовсе: наведение, выбор и тревога включались
       скачком, а вдавливание дёргалось. Цвет/рамка/тень едут на месте (--dur-state), transform —
       возврат с пружиной; само нажатие сухое и короткое (ниже, :active). */
    transition:background-color var(--dur-state) var(--ease-standard),border-color var(--dur-state) var(--ease-standard),
      color var(--dur-state) var(--ease-standard),box-shadow var(--dur-state) var(--ease-standard),
      transform var(--dur-release) var(--ease-spring)}
  /* НАВЕДЕНИЕ (blox52 #3, п.6). У чипа группы были заведены только нажатие и «выбран», а состояния
     наведения не было ВООБЩЕ — при том что у соседних контролов (призрачная кнопка, кебаб,
     плитка хаба) оно есть. Тот же ключ, что у них: тёмный акцент линией (--accent-deep — акцент
     ЛИНИЕЙ, а не заливкой, см. theme.css), акцентная подложка и тень на ступень выше.
     Объявлено ДО .gchip.on намеренно: у выбранного чипа рамка обязана остаться акцентными
     чернилами, поэтому его правило идёт следом и побеждает при равной специфичности. */
  @media (hover:hover){.gchip:hover{border-color:var(--accent-deep);background:var(--accent-tint);
    box-shadow:var(--sh-2)}}
  .gchip:active{transform:scale(var(--press-scale));
    transition-duration:var(--dur-press-in);transition-timing-function:var(--ease-standard)}
  /* кольцо фокуса ВНУТРЬ: лента прокручивается (overflow), и внешнее кольцо срезалось бы её краем */
  .gchip:focus-visible{outline:none;box-shadow:var(--sh-1),var(--ring-inset)}
  @media (prefers-reduced-motion:reduce){.gchip:active{transform:none}}
  /* ОТМЕТКА «всё сделано» (blox59 #5). Была точка 8px цвета --checked на два смысла: зелёная —
     «порядок», красная — «ДЗ не выдано». Красную сняли — о тревоге и так кричит рамка чипа, а
     точка с рамкой повторяли друг друга. Оставшийся смысл один и положительный, поэтому и знак
     стал прямым: ГАЛОЧКА. Цвет — --ok-ink, а не заливочный --ok: у тонкого штриха контраст
     считается по линии, и целадон-500 на бумаге её бы утопил. Размер задан в em (иконка и так
     1.15em от текста), чтобы отметка ехала со шкалой шрифта чипа.
     blox59 #6: перо ЖИРНЕЕ (--icw 2.6 против 1.75 по умолчанию — толщину пускает внутрь чужого
     документа только эта переменная, снаружи стилем до штриха не дотянуться, см. icons.svg) и
     сама галочка ПИСАНАЯ, с изгибом обоих плеч (i-check-soft). */
  .gchip .gtick{width:1.15em;height:1.15em;color:var(--ok-ink);flex:0 0 auto;--icw:2.6}
  /* ТРЕВОГА ЧИПА — снова КРАСНАЯ, но на узком факте (blox59 #4, решение владельца 16.09.2026).
     История в двух шагах. Сначала (blox51 #3) чип красился ЦЕЛИКОМ по флагу r.alert — «нет ДЗ
     ИЛИ черновик ИЛИ есть непроверенные сдачи»; в живой школе это верно почти всегда, и лента
     краснела вся, поэтому цвет сняли. Потом (blox52 #11) остаток тревоги перевели в акцент
     схемы. Итог: экран перестал отличать «работа не сделана» от «работа в очереди».
     Возврат сделан не откатом, а СУЖЕНИЕМ предиката: класс .alert теперь ставится по r.nohw —
     ближайший урок не выдан (пусто или черновик), — а непроверенные сдачи красного больше не
     дают, у них свой счётчик в акценте. Таких чипов на ленте один-два, красный снова редок.
     Заливка чипа НЕ красится (это и была «красная стена»): тревогу несут точка и рамка.
     Правило стоит ПОСЛЕ :hover намеренно — под курсором тревога обязана остаться (тот же
     приём, что у .lday:hover перед состояниями дня).
     blox59 #5: тревога носит ТОЛЬКО плоскость и рамку. Красная точка ушла — она говорила ровно
     то же, что рамка, и была второй пометкой об одном факте; к тому же точку забирал себе
     счётчик «к проверке», и группа «ДЗ не выдано + 3 к проверке» теряла бы красный совсем.
     blox59 #6 (решение владельца): ЗАЛИВКА вернулась — как было до blox51 #3. Тогда её сняли
     из-за широкого флага r.alert, поднятого почти всегда; теперь чип красит r.alarm, который
     молчит и при непроверенных сдачах, и у групп с плейлистом, так что красных чипов на ленте
     единицы и стены из них не выходит.
     blox59 #7 (решение владельца): ИМЯ ГРУППЫ НЕ КРАСИМ. Красные чернила были третьей пометкой об
     одном факте (заливка · рамка · текст), и они перекрашивали единственное, что на чипе несёт
     СОДЕРЖАНИЕ, а не состояние: имя группы читают, чтобы найти нужную, а не чтобы узнать про ДЗ.
     Цвет текста остаётся общим — --muted у невыбранного чипа, --ink у выбранного. */
  .gchip.alert{border-color:var(--alert-line);background:var(--alert-tint)}
  /* НАВЕДЕНИЕ НА ТРЕВОЖНЫЙ ЧИП (blox59 #10). У обычного чипа наведение есть (правило выше), а у
     покрасневшего его не было ВООБЩЕ: .gchip.alert объявлен ПОЗЖЕ .gchip:hover и при большей
     специфичности перекрывал и рамку, и подложку — под курсором тревожный чип не шевелился, и
     человек переставал понимать, что он нажимается. Ответ тот же по СМЫСЛУ, но в своей семье
     цветов: подложка на ступень гуще (--alert-fill, 22% пигмента против 12% у тинта — это и есть
     «затемнение»), рамка глубже (сплошной --alert вместо бледного --alert-line), тень на ступень
     выше — ровно как обычный чип отвечает --accent-deep вместо --line.
     Стоит ПЕРЕД .gchip.on.alert намеренно: у ВЫБРАННОГО тревожного чипа подложка обязана остаться
     своей, он и так помечен полоской, — тот же закон, по которому обычный .gchip.on не берёт
     заливку наведения. */
  @media (hover:hover){.gchip.alert:hover{border-color:var(--alert);
    background:var(--alert-fill);box-shadow:var(--sh-2)}}
  /* blox52 #12 — у активного чипа была ДВОЙНАЯ пометка: рамка 1.5px И полоска. Рамку сняли,
     осталась одна система: живая полоска .gind + лёгкая заливка чипа (замер контраста заливки
     не нужен — текст на ней те же чернила --ink). Полоска цвета --accent-ink — выбор blox52 #7:
     в синих схемах сам акцент (светлый Maya) давал на столе 1.53:1, чернила той же Maya — 4.55. */
  .gchip.on{color:var(--ink);background:var(--accent-tint)}
  /* ВЫБРАННЫЙ И ТРЕВОЖНЫЙ. .gchip.on объявлен ПОСЛЕ .gchip.alert и при равной специфичности
     перекрасил бы тревожный чип акцентом, стоит его выбрать (та же ловушка порядка, что в
     blox52 #9 с рамкой панели). Лечится не !important, а третьим классом в селекторе: тревога
     держит свою заливку, а «выбран» читается полоской .gind и рамкой погуще. */
  .gchip.on.alert{border-color:var(--alert);background:var(--alert-tint)}
  /* индикатор выбранной группы (blox52 #12): БЫЛ ::after на каждом чипе — у псевдоэлемента нет
     пути ЕХАТЬ от чипа к чипу, подчёркивание перепрыгивало. Теперь это ОДИН общий узел .gind в
     ряду чипов (позицию ставит paintGind, core.js): transform/width едут ~200мс, и выбор ЕДЕТ
     к новому чипу. top/width — инлайном из JS (геометрия чипа), здесь только вид и движение. */
  .gind{position:absolute;left:0;top:0;height:3px;width:0;border-radius:var(--r-2xs);
    background:var(--accent-ink);pointer-events:none;
    transition:transform var(--dur-state) var(--ease-standard),width var(--dur-state) var(--ease-standard)}
  /* «выбрано» и «тревожно» — разные факты, и подчёркивание выбора говорило о втором.
     Выделение снова окрашено только акцентом, каким бы ни был флаг тревоги. */
  /* счётчик «к проверке» — очередь, не пожар (blox52 #11): акцент схемы, как у плашки
     «Check N» в ростере. Ховер — лёгкое высветление той же заливки, не смена цвета. */
  .gchip .gn{font-weight:800;font-size:var(--fs-2xs);color:var(--on-dark);background:var(--anchor);
    border-radius:var(--r-xs);padding:1px 6px;cursor:pointer}
  @media (hover:hover){.gchip .gn:hover{filter:brightness(1.15)}}
  /* СТРОКА ИНСТРУМЕНТОВ ГРУППЫ (blox31 #1 · переработана blox53 #1–#5): гамбургер · Post · Chat.
     Ровно три кнопки, ОДИН ряд на любой ширине. Ушли имя группы (оно написано на выбранном чипе
     ленты строкой ниже), «Notes» (досье открывает тумблер на левом листе) и «Playlist» (туда
     ведёт плашка плейлиста на панели) — на телефоне строка была двухэтажной именно из-за них. */
  .ghead-tools{display:flex;flex-wrap:nowrap;align-items:center;gap:8px;margin:4px 0 12px}
  .ghead-tools .btn-ghost{display:flex;align-items:center;justify-content:center;gap:6px;
    flex:0 1 auto;min-width:0;white-space:nowrap}
  .ghead-tools .gt-post{margin-left:auto}   /* гамбургер слева, Post+Chat правой кучкой */
  /* кнопка-гамбургер — прячет редкие действия (Ученики / Расписание / + Группа), blox31 #1.
     Меню всплывает под ней; [hidden] гасит его через display:none (правило 7 skill). */
  .gkebab-wrap{position:relative;display:inline-flex;align-items:center}
  .gkebab{width:38px;height:38px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--card);
    color:var(--muted);font-size:var(--ic-md);line-height:1;cursor:pointer;
    display:flex;align-items:center;justify-content:center}
  @media (hover:hover){.gkebab:hover{border-color:var(--accent-deep);background:var(--accent-tint);color:var(--accent-ink)}}
  /* ОТКЛИК И ОТКРЫТОЕ СОСТОЯНИЕ (ночной редизайн 27.10, агент 4 — по образцу шестерёнки .set-btn):
     сухо вдавливается, пружиной назад; пока меню раскрыто, кнопка держит вид наведения — видно, ЧЬЁ
     это меню. Палец — 44px: кнопка 38px видом, касание ловит невидимый ободок 3px (строка не растёт). */
  .gkebab{position:relative;
    transition:background-color var(--dur-state) var(--ease-standard),border-color var(--dur-state) var(--ease-standard),
      color var(--dur-state) var(--ease-standard),transform var(--dur-release) var(--ease-spring)}
  .gkebab:active{transform:scale(var(--press-scale-sm));
    transition-duration:var(--dur-press-in);transition-timing-function:var(--ease-standard)}
  .gkebab[aria-expanded="true"]{border-color:var(--accent-deep);background:var(--accent-tint);color:var(--accent-ink)}
  @media (pointer:coarse){.gkebab::before{content:"";position:absolute;inset:-3px;border-radius:inherit}}
  @media (prefers-reduced-motion:reduce){.gkebab:active{transform:none}}
  /* меню якорится по ЛЕВОМУ краю кнопки на ЛЮБОЙ ширине. Центрированное (left:50% + сдвиг на
     половину) уезжало за край экрана, потому что гамбургер стоит первым в строке: меню шириной
     190px наполовину вылезало влево, и «Ученики/Расписание/Группа» читались как «ченики/асписание/
     уппа». На телефоне это чинили ещё в blox31 #1 отдельным правилом, а на ПК гамбургер тогда
     стоял НЕ с краю (перед ним были имя группы и другие кнопки) — левый край его прикрывал. В
     blox53 #1–#5 строку сократили до трёх кнопок, гамбургер выехал в начало и на ПК — и центровка
     сломалась там же. Поэтому правило одно на все ширины, отдельного телефонного больше нет. */
  .gkebab-menu{position:absolute;top:calc(100% + 6px);left:0;z-index:45;
    display:flex;flex-direction:column;gap:4px;min-width:190px;padding:8px;
    background:var(--card);border-radius:var(--r-lg);box-shadow:var(--sheet-pop)}
  .gkebab-menu[hidden]{display:none}
  /* ПОЯВЛЕНИЕ И УХОД (ночной редизайн 27.10) — тот же рецепт, что у меню шестерёнки .set-menu: меню
     открывает/закрывает атрибут hidden (teacher.js, wireHead), display none ↔ flex. @starting-style
     даёт приезд — проявление и короткий спуск из-под кнопки (половина --enter-shift), угол роста —
     левый верхний, у гамбургера; allow-discrete держит меню на экране, пока оно гаснет. Закрытое
     (гаснущее) меню касаний не ловит: JS уже считает его закрытым. В покое transform нет. */
  .gkebab-menu{transform-origin:top left;opacity:1;translate:none;
    transition:opacity var(--dur-panel-out) var(--ease-exit),translate var(--dur-panel-out) var(--ease-exit),
      display var(--dur-panel-out);
    transition-behavior:allow-discrete}
  .gkebab-menu[hidden]{opacity:0;translate:0 calc(var(--enter-shift) / -2);pointer-events:none}
  .gkebab-menu:not([hidden]){transition-duration:var(--dur-panel);transition-timing-function:var(--ease-enter)}
  @starting-style{.gkebab-menu:not([hidden]){opacity:0;translate:0 calc(var(--enter-shift) / -2)}}
  .gkebab-menu .btn-ghost,.gkebab-menu .btn{width:100%;justify-content:flex-start;gap:8px}
  /* ПК (blox69 #1): гамбургер раскрыт — его пункты стоят обычными кнопками у левого края строки,
     Post+Chat остаются правой кучкой. Ключ — мышь (hover+fine), а не одна ширина: планшет в
     альбомной ориентации широк, но палец там тот же, и гамбургер ему удобнее. От 900px: уже
     шести кнопкам в ряд тесно. Меню не
     пересобирается и обработчики не меняются — только раскладка тех же узлов, поэтому `hidden`
     перебивается здесь (display в CSS сильнее атрибута — правило 7 skill). */
  @media (min-width:900px) and (hover:hover) and (pointer:fine){
    .gkebab{display:none}
    /* z-index:auto — blox73 #4. Меню здесь static, но оно ФЛЕКС-ЭЛЕМЕНТ (.gkebab-wrap — inline-flex),
       а у флекс-элемента z-index работает и без position. Его 45 от выпадашки оказывался выше
       липкой шапки (40), и на ПК при прокрутке четыре кнопки ехали ПОВЕРХ шапки, а Post/Chat — под ней. */
    .gkebab-menu,.gkebab-menu[hidden]{display:flex;position:static;z-index:auto;flex-direction:row;align-items:center;
      gap:8px;min-width:0;padding:0;background:none;box-shadow:none;border-radius:0;
      opacity:1;translate:none;pointer-events:auto;transition:none}   /* раскрытая строка — не всплывашка: не гаснет и не приезжает */
    .gkebab-menu .btn-ghost,.gkebab-menu .btn{width:auto;white-space:nowrap}
  }
  /* blox69 #3 — «Другие группы» у методиста. Нажатая кнопка ВДАВЛЕНА (владелец: «чтобы кнопка
     как бы зажималась»): внутренняя тень нажатия и тон колодца держатся, пока ряд учителей открыт.
     Сам ряд — те же вкладки .sb-tab, что у переключателя учителей в расписании Лу. Прячется
     атрибутом hidden, а у .sb-tabs свой display:flex, который атрибут перебил бы (правило 7). */
  .ghead-tools .gt-others.on{box-shadow:var(--sh-press);background:var(--surface);
    border-color:var(--accent-deep);color:var(--accent-ink)}
  .gteach{margin:-4px 0 12px}
  .gteach[hidden]{display:none}
  /* blox72 #1 — РЕЖИМ ПРОСМОТРА чужой группы (body.ro-view ставит монитор, core.js setRoView).
     Всё, что меняет данные, экраны помечают data-w — здесь оно пропадает целиком. !important
     нарочно: у кнопок свои display (flex/inline-flex), и тихо проигрывать им нельзя — оставшаяся
     кнопка записи и есть та дыра, которую режим закрывает. Сервер всё равно ответит 403. */
  body.ro-view [data-w]{display:none !important}
  /* плашка «Только просмотр» над лентой групп: говорит, ПОЧЕМУ нет кнопок правки */
  .ro-note{display:none}
  body.ro-view .ro-note{display:flex;align-items:center;gap:6px;margin:-4px 0 10px;padding:6px 10px;
    border-radius:var(--r-sm);background:var(--surface);color:var(--muted);font-size:.9em}
  /* телефон (blox53 #4) — те же три кнопки, просто теснее: Post и Chat делят остаток строки
     поровну, гамбургер держит свои 38px. */
  @media(max-width:760px){
    .ghead-tools .gt-post,.ghead-tools .gt-chats{
      flex:1 1 0;font-size:var(--fs-sm);gap:4px;padding-left:4px;padding-right:4px;
      min-width:32px;min-height:32px}   /* цель касания ≥24px даже в тесной шапке (axe target-size) */
  }

  /* pupil's "where I study" line: отделение · группа · учитель (blox10 #2) */
  /* строка «где я учусь» не должна липнуть к заголовку — своя воздушная подушка (blox13 #3) */
  .swhere{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:8px 0 16px;
    font-size:var(--fs-sm);color:var(--muted);font-weight:600}
  .swhere-grp{font-weight:800;color:var(--ink)}
  .swhere-sep{color:var(--faint)}

  /* pupil's lesson carousel — flip among days that have homework */
  .lcar{display:flex;align-items:center;justify-content:space-between;gap:10px;
    background:var(--card);border-radius:var(--r-lg);padding:8px 10px;
    margin:0 0 16px;box-shadow:var(--sheet-1)}
  .lcar-arr{width:44px;height:44px;flex:none;border:1px solid var(--line);background:var(--card);
    border-radius:var(--r-md);font-size:var(--ic-md);color:var(--ink);cursor:pointer;
    transition:background-color var(--dur-state) var(--ease-standard),border-color var(--dur-state) var(--ease-standard),
      transform var(--dur-release) var(--ease-spring)}
  @media (hover:hover){.lcar-arr:hover:not(:disabled){background:var(--accent-tint);border-color:var(--accent-deep)}}
  .lcar-arr:active:not(:disabled){transform:scale(var(--press-scale-sm));
    transition-duration:var(--dur-press-in);transition-timing-function:var(--ease-standard)}
  @media (prefers-reduced-motion:reduce){.lcar-arr:active:not(:disabled){transform:none}}
  /* ВЫКЛЮЧЕНО ГОВОРЯТ РОЛИ ЦВЕТА, А НЕ ПРОЗРАЧНОСТЬ (blox52 #4, п.7). Кнопочный движок
     перевели на это в blox52 #3, а вне его «выключено» оставалось написанным шестью
     разными числами (.28 · .3 · .45 · .55 · .9 и отдельно обесцвечивание) — одна роль,
     шесть значений. Прозрачность вдобавок гасит предмет ЦЕЛИКОМ вместе с подписью и
     протаскивает сквозь него то, на чём он лежит, поэтому вид зависел от подложки.
     Рецепт один и тот же везде: заливка гаснет в нейтральную --fill-soft, текст — в
     --faint, рамка — в волосок. */
  .lcar-arr:disabled{background:var(--fill-soft);border-color:var(--line-soft);
    color:var(--faint);cursor:default}
  .lcar-mid{text-align:center;line-height:1.25}
  .lcar-date{font-weight:800;font-size:var(--fs-lg);color:var(--ink);letter-spacing:var(--tracking-tight)}
  .lcar-pos{font-size:var(--fs-xs);color:var(--faint);margin-top:2px}

  /* (blox52 #11) Блок .lh/.elist/.ecard старого монитора-списка удалён: ни один модуль эти
     классы больше не рисует (экран заменён .oent-плашками), а .ecard .enotdone был ещё одним
     красным текстом-сиротой. */
  /* тема = РАМКА, оборачивающая таски; скруглена с ЗАКРЫТОЙ стороны, ОТКРЫТА с другой.
     blox26 #5 — ЕДИНЫЙ визуал на ВСЕХ экранах: одна толщина (1.5px), цвет — токен схемы
     var(--frame-line) (перекрашивается вместе с палитрой), фон ПРОЗРАЧНЫЙ. Три класса
     остаются лишь потому, что различается ВНУТРЕННЯЯ раскладка/плотность:
       .tframe — Домашка ученика + проверка учителем
       .oframe — монитор учителя (плотнее)
       .theme  — постановка/редактирование ДЗ
     поэтому padding/margin и заголовки у каждого свои, а рамка — общая. */
  .tframe,.oframe,.theme,.cpk-frame{position:relative;background:transparent;--fpad:14px;--frail:6px}
  /* сама скобка — ПСЕВДОЭЛЕМЕНТ, а не border самого блока. Это позволяет «усам» (верхней
     и нижней линиям) КОНЧАТЬСЯ на открытом крае карточек, а не торчать до края блока
     (blox26 #5). --fpad = паддинг рамки с ОТКРЫТОЙ стороны = насколько подтянуть усы.
     Карточки при этом НЕ двигаются — выравнивание с тасками «вне темы» сохраняется.
     ОРИЕНТАЦИЯ (blox50 #5): закрытый скруглённый край — СПРАВА, открытая грань — СЛЕВА.
     Это единственный вид рамки; тумблер «Обычная/Зеркальная» (blox26 #5) убран, выбранный
     вид закреплён для всех. Открытая сторона совпадает со стороной цветного рельса таска
     (он всегда слева), поэтому усы подтянуты внутрь ещё на ШИРИНУ рельса (--frail): ус
     кончается там, где рельс ЗАКАНЧИВАЕТСЯ, и цветная окантовка целиком торчит наружу.
     (У монитора рельс тоньше — --frail:3px.) */
  .tframe::before,.oframe::before,.theme::before,.cpk-frame::before{content:"";position:absolute;
    top:0;bottom:0;left:calc(var(--fpad) + var(--frail));right:0;
    border:1.5px solid var(--frame-line);border-left:none;
    border-radius:0 var(--r-xl) var(--r-xl) 0;pointer-events:none}
  .tframe{padding:4px 14px 14px;margin:0 0 20px}
  .tframe>.tfh{text-align:center;font-weight:800;font-size:var(--fs-lg);color:var(--ink);
    letter-spacing:var(--tracking-tight);padding:11px 0 13px}
  .tframe>.tfcards{display:flex;flex-direction:column;gap:10px}
  /* таск ВНЕ темы — та же ширина, что и в рамке (сдвиг вправо на границу+паддинг рамки).
     Домашка ученика + экран проверки; в черновике ту же роль играет .standarea. */
  .hwlist>.sloose,.srlist>.sloose{margin-left:15px;margin-right:14px}
  .sortbar{display:flex;align-items:center;gap:10px;margin:18px 0 8px}
  .sortbar .sortlbl{font-weight:800;font-size:var(--fs-sm);color:var(--ink)}
  .seg{display:inline-flex;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
  .seg button{border:0;background:var(--card);color:var(--muted);font-weight:700;font-size:var(--fs-xs);
    padding:7px 13px;cursor:pointer;transition:background var(--t-fast) var(--ease)}
  /* blox51 #3 (заход 3.2): выбранный сегмент — ЯКОРЬ схемы под белым текстом, как у всех
     остальных сегментных переключателей. Раньше здесь была светлая акцентная заливка с тёмным
     текстом; в базовой схеме акцент ушёл в чёрный, и пара «тёмное на тёмном» стала нечитаемой.
     Якорь работает в обеих сторонах: он тёмный в КАЖДОЙ схеме, и белый на нём проходит AA. */
  .seg button.on{background:var(--anchor);color:var(--on-dark)}
  .rlist{display:flex;flex-wrap:wrap;gap:8px}
  .rchip{display:flex;align-items:center;gap:10px;border:1px solid var(--line-soft);background:var(--card);
    border-radius:var(--r-sm);padding:8px 12px;cursor:pointer;font-weight:700;color:var(--ink);
    transition:border-color var(--t) var(--ease),background var(--t) var(--ease),
               box-shadow var(--t) var(--ease)}
  @media (hover:hover){.rchip:hover{border-color:var(--accent-deep)}}
  /* ПОДСВЕТКА ОТ ПЛАШКИ-ФИЛЬТРА (blox52 #12 · перекрашена и замедлена в blox55 #6): клик по
     .oent-live метит чипы учеников из её списка «не сделали». Только цвет и кольцо-тень —
     размеры не меняются, прокрутка на месте (кольцо box-shadow вне потока).
     ЦВЕТ — АЛЕРТНЫЙ, не якорь схемы: вспышка читается как «вот кого не хватает» и должна
     находиться глазом мгновенно; прежний якорь был почти неотличим от обычного hover чипа.
     ВРЕМЯ — 1.8с вместо 600мс (втрое), и обе половины вспышки ПЛАВНЫЕ: проявление (fade-in,
     0→22% ≈ 0.4с, ease-out — быстро набирает и мягко упирается), плато до 40%, затем долгое
     угасание (fade-out) до нуля. Ступеньки нет ни на входе, ни на выходе. Класс .hl снимается
     в teacher.js по тому же таймеру — уже после того, как цвет сошёл на нет. */
  /* края кадров НЕ перечисляют цвета нарочно: пустой 0%/100% браузер заполняет собственными
     значениями чипа, так что вспышка входит из его нормального вида и в него же возвращается —
     и рецепт листа (белая карточка обязана носить тень из семейства --sheet) не нарушается. */
  @keyframes rchip-hl{
    0%{box-shadow:0 0 0 0 transparent;animation-timing-function:cubic-bezier(.2,.7,.3,1)}
    22%,40%{border-color:var(--alert);background:var(--alert-tint);box-shadow:0 0 0 1.5px var(--alert)}
    100%{box-shadow:0 0 0 0 transparent}
  }
  .rchip.hl{animation:rchip-hl 1800ms var(--ease) both}
  /* без движения — та же пометка, просто без плавности: она обязана остаться видимой */
  @media (prefers-reduced-motion:reduce){
    .rchip.hl{animation:none;border-color:var(--alert);background:var(--alert-tint);
      box-shadow:0 0 0 1.5px var(--alert)}
  }
  /* review badge — единый английский словарь (blox52 #11): «Check N» (акцент схемы) /
     «✓» (зел., blox84 #6; было «N of N · Done!») / «✓ N of N» (зел. тинт) / Nope (серый). nowrap — плашка в колонке
     148px (.oroster) не имеет права рваться на две строки: перенос вешал точку-разделитель
     «·» в конец строки (дефект Б1 второго прогона судей). */
  .rchip .rrev{font-size:var(--fs-xs);font-weight:800;padding:2px 8px;border-radius:var(--r-xs);
    white-space:nowrap}
  /* «сдано, ждёт проверки» — ОЧЕРЕДЬ РАБОТЫ, а не провал (blox52 #11): ребёнок сделал всё
     правильно, действовать надо учителю. Очередь говорит акцентом СВОЕЙ схемы — якорь под
     белым текстом (баклажан 10.8:1 · графит 13.8 · Maya 6.0 · виноград 5.3, замер 06.09.2026);
     красная заливка остаётся настоящим тревогам (реестр RED_OK в tools/check.js). */
  .rchip .rrev.pend{color:var(--on-dark);background:var(--anchor)}
  .rchip .rrev.done{color:var(--ok-ink);background:var(--ok-fill)}
  .rchip .rrev.checked{color:var(--ok);background:var(--ok-tint)}
  .rchip .rrev.nope{color:var(--muted-strong);background:var(--fill-soft)}   /* «ничего не сдал» за прошедший урок — факт, не тревога: серым, не цветом alert (blox22 #1). grape-600, а не --muted: на grape-100 у --muted было 4.34:1 */

  /* ═══════════════════════════════════════════════════════════════════════
     ПЕРЕРИСОВКА B — ЛЕНТА ГРУПП И СТРОКИ НА ПОЛОСЕ (агент 2, эскиз MonB). Всё, что лежит на
     полосе группы (.gband, style-01-chrome.css), говорит долями белого (--on-group-*), а не
     цветом: полоса бывает восьми цветов и ночной. Классы и id прежние — JS и пробы их ищут. */
  /* шторки края ленты — цвета полосы, а не стола: иначе по краям ленты горели бы светлые мазки */
  .gband .gstrip{--strip-bg:var(--group);gap:6px;padding:4px 2px 8px;margin-bottom:0}
  /* ЧИП ГРУППЫ: невыбранный — прозрачный с белым контуром 1px (эскизные 1.5 — мимо лестницы линий; доля белого .5 вместо .45 возвращает вес), выбранный — белый с текстом
     цвета группы. Высота 36 видом (эскиз), касание — 44: невидимый ободок 4px сверху и снизу
     (лента даёт ему место паддингом 4px). Рамка ВЫБРАННОГО — тот же контур, что у соседей:
     «выбран» несут заливка и живое подчёркивание .gind (одна система, blox52 #12). */
  .gband .gchip{height:36px;box-sizing:border-box;padding:0 14px;gap:6px;
    border:1px solid var(--on-group-line);border-radius:var(--r-chip);
    background:transparent;color:var(--on-group);box-shadow:none;
    font-size:var(--fs-ctl);font-weight:600}
  @media (pointer:coarse){.gband .gchip::before{content:"";position:absolute;inset:-4px 0;border-radius:inherit}}
  /* наведение — подложка гуще И контур сплошной белый (проба blox52 #3 требует обе перемены) */
  @media (hover:hover){.gband .gchip:hover{background:var(--on-group-hover);border-color:var(--on-group);box-shadow:none}}
  .gband .gchip:focus-visible{box-shadow:var(--ring-inset)}
  .gband .gchip.on{background:var(--on-group);color:var(--group)}
  /* «ДЗ не выдано» — красный ТИНТ (эскиз MonB: Eggplant). Имя группы остаётся чернилами, а не
     красным: имя читают, чтобы найти группу (решение владельца blox59 #7, см. правило выше). */
  .gband .gchip.alert{background:var(--alert-tint);border-color:var(--alert-tint);color:var(--ink)}
  /* наведение тревожного — в своей семье цветов, как вне полосы (blox59 #10): рамка --alert,
     подложка гуще, тень на ступень */
  @media (hover:hover){.gband .gchip.alert:hover{background:var(--alert-fill);border-color:var(--alert);box-shadow:var(--sh-2)}}
  .gband .gchip.on.alert{background:var(--alert-tint);border-color:var(--on-group);color:var(--ink)}
  .gband .gind{background:var(--on-group)}
  /* счётчик «к проверке» на чипе — «ждёт учителя» = цвет группы (как «Check N» на ростере):
     на прозрачном чипе — белая плашка с текстом цвета группы, на выбранном белом — наоборот */
  .gband .gchip .gn{background:var(--on-group);color:var(--group);border-radius:var(--r-badge);font-weight:700}
  .gband .gchip.on .gn,.gband .gchip.alert .gn{background:var(--group);color:var(--on-group)}
  /* строка инструментов на полосе: те же кнопки, вид «на полосе» даёт .gband .btn-ghost (style-06) */
  .gband .ghead-tools{margin:0 0 10px}
  .gband .gkebab{border:1px solid var(--on-group-line);background:transparent;color:var(--on-group);
    border-radius:var(--r-btn);width:44px;height:44px}
  @media (hover:hover){.gband .gkebab:hover{border-color:var(--on-group);background:var(--on-group-hover);color:var(--on-group)}}
  .gband .gkebab[aria-expanded="true"]{border-color:var(--on-group);background:var(--on-group-hover);color:var(--on-group)}
  /* нажатая «Другие группы» остаётся ВДАВЛЕННОЙ (внутренняя тень, blox69 #3), на полосе — белой */
  .gband .ghead-tools .gt-others.on{box-shadow:var(--sh-press);background:var(--on-group);color:var(--group);border-color:var(--on-group)}
  /* «Только просмотр» на полосе — белая полупрозрачная плашка */
  body.ro-view .gband .ro-note{background:var(--on-group-fill);color:var(--on-group)}
  /* «где я учусь» у ребёнка — на полосе белым (эскиз HwB) */
  .gband .swhere,.gband .swhere-grp,.gband .swhere-sep{color:var(--on-group)}
  .gband .swhere{margin:4px 0 0}
  /* ═══ ПЕРЕРИСОВКА B — БЕЙДЖИ РЕБЁНКА (агент 2, эскиз MonB): Nope · Check N · ✓ N of N · ✓ ═══
     Смысл к цвету прежний, краска B: «Check N» (ждёт учителя) — цвет ГРУППЫ под белым (на трёх
     экранах полосы --group стоит на body; вне их — цвет по умолчанию), «✓» — зелёный тинт с
     тёмно-зелёным текстом, «Nope» — серая заливка. Мелкий бейдж: 11px/600, скругление 6. */
  .rchip .rrev{font-size:var(--fs-2xs);font-weight:600;line-height:1.3;padding:2px 6px;border-radius:var(--r-badge)}
  .rchip .rrev.pend{color:var(--on-group);background:var(--group)}
  .rchip .rrev.done,.rchip .rrev.checked{color:var(--ok-ink);background:var(--ok-fill)}
  .rchip .rrev.nope{color:var(--muted);background:var(--fill-soft)}
  /* ═══ ПЕРЕРИСОВКА B — ЛИСТ-КАРТОЧКА .panel (агент 2): белая карточка B без тени, радиус
     карточки 16. Край на светлом столе B читается контрастом белого к #f1f3f5. */
  .panel{border-radius:var(--r-card);box-shadow:none}
  /* ═══ ПЕРЕРИСОВКА B — КРУЖОК С ИНИЦИАЛАМИ .ava (агент 2; разметку даёт avaHTML(name, size) из
     public/format.js — через core.js). Две буквы витринным шрифтом, тинт группы, буквы цветом
     группы (пара ≥4.5:1 днём и ночью — tools/unit/group-color.test.mjs). Размеры эскизов:
     34px/13 (плитка ростера MonB) и 40px/14 (.ava--lg, карточка сдачи ReviewB). */
  .ava{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
    width:34px;height:34px;border-radius:50%;background:var(--group-tint);color:var(--group-ink);
    font-family:var(--font-display);font-weight:var(--fw-display);font-size:var(--fs-initials);
    line-height:1;letter-spacing:0;user-select:none}
  .ava--lg{width:40px;height:40px;font-size:var(--fs-initials-lg)}
