/* admin.css — minimal underwater-toned admin styling. */
:root {
  --c-bg: #0b2a3a;
  --c-bg-alt: #0f3a4f;
  --c-card: #143f55;
  --c-text: #e6f4ff;
  --c-text-dim: #9bbfd4;
  --c-accent: #46c8ff;
  --c-accent-soft: #275a72;
  --c-border: #1f5570;
  --c-error: #ff6b6b;
  --c-ok: #6be09a;
  --c-warn: #ffd17a;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  /*
   * UX-pass-2026-05 (research-driven): cyrillic-first font stack. Segoe UI
   * на Windows, SF Pro Text на macOS, system-ui для Linux/Android. Это
   * закрывает known issue с full-width-cyrillic в некоторых системных
   * шрифтах (см. misskey#13368) и даёт куратору привычный шрифт ОС.
   */
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, system-ui, "Helvetica Neue", Roboto, sans-serif;
  /*
   * UX-pass-2026-05 (research-driven): line-height 1.55 для базового
   * текста — кириллица заметно выигрывает от чуть большего интерлиньяжа
   * по сравнению с латиницей. Куратор работает дома вечером по часу+,
   * на ноутбуке без внешнего монитора. WCAG 2.2 AAA рекомендует ≥1.5.
   */
  line-height: 1.55;
  background: linear-gradient(180deg, var(--c-bg) 0%, var(--c-bg-alt) 100%);
  color: var(--c-text);
  min-height: 100vh;
}

main {
  display: block;
}

/*
 * N-MAJ-01 audit fix: the previous `main:focus { outline: none }` swallowed
 * the focus ring on the skip-link landing target, breaking keyboard nav.
 * Replaced with a `:focus-visible` outline so the keyboard-only path keeps
 * a visible cue and pointer focus stays clean.
 */
main:focus-visible {
  outline: 2px dashed var(--c-accent);
  outline-offset: -4px;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: 8px;
  background: var(--c-accent);
  color: #003047;
  padding: 10px 16px;
  border-radius: 6px;
  font-weight: 600;
  text-decoration: none;
  z-index: 1000;
  transition: top 0.15s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 8px;
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}

/*
 * N-MAJ-02 audit fix: standard "visually hidden" recipe for the
 * "(открывается в новой вкладке)" warning that we attach to every
 * target="_blank" link. Screen readers announce it; sighted users
 * see the visible "↗" glyph immediately before this span.
 */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 24px;
}

.brand {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
h1.brand {
  margin: 0;
}

.brand-sub {
  color: var(--c-text-dim);
  font-size: 13px;
  margin-top: 2px;
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 24px;
  background: rgba(0, 0, 0, 0.2);
  border-bottom: 1px solid var(--c-border);
}

.nav a {
  color: var(--c-text);
  text-decoration: none;
  margin-right: 16px;
}

.nav a:hover { color: var(--c-accent); }

.card {
  background: var(--c-card);
  border: 1px solid var(--c-border);
  border-radius: 10px;
  padding: 24px;
  margin-bottom: 16px;
}

label {
  display: block;
  margin-top: 12px;
  color: var(--c-text-dim);
  font-size: 14px;
}

.req {
  color: var(--c-error);
  margin-left: 2px;
  font-weight: 700;
}

input[type="text"], input[type="password"], textarea, select {
  width: 100%;
  padding: 10px 12px;
  background: var(--c-bg);
  border: 1px solid var(--c-border);
  border-radius: 6px;
  color: var(--c-text);
  font-size: 15px;
  margin-top: 4px;
}

input:focus, textarea:focus, select:focus,
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 1px;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 2px rgba(70, 200, 255, 0.2);
}

input[aria-invalid="true"] {
  border-color: var(--c-error);
}
input[aria-invalid="true"]:focus,
input[aria-invalid="true"]:focus-visible {
  outline-color: var(--c-error);
  box-shadow: 0 0 0 2px rgba(255, 107, 107, 0.25);
}

.field-error {
  color: var(--c-error);
  font-size: 13px;
  margin: 4px 0 0;
}

/* N-MIN / Block 6: live character counter sibling for [data-show-counter]. */
.char-counter {
  display: block;
  font-size: 12px;
  color: var(--c-text-dim);
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.char-counter-warn { color: var(--c-warn); }
.char-counter-max  { color: var(--c-error); font-weight: 600; }

.btn {
  display: inline-block;
  padding: 10px 18px;
  background: var(--c-accent);
  color: #003047;
  border: none;
  border-radius: 6px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  font-size: 15px;
}
.btn:hover { background: #6fd6ff; }
.btn:focus-visible {
  outline: 2px solid var(--c-text);
  outline-offset: 2px;
}
.btn[disabled],
.btn[aria-disabled="true"] {
  background: var(--c-accent-soft);
  color: var(--c-text-dim);
  cursor: not-allowed;
}
.btn-secondary {
  background: var(--c-accent-soft);
  color: var(--c-text);
}
.btn-secondary:hover { background: #2c6e8a; }
.btn-danger {
  background: var(--c-error);
  color: #260000;
  font-weight: 700;
}
.btn-danger:hover { background: #ff8a8a; }
.btn-danger:focus-visible {
  outline: 2px solid var(--c-text);
  outline-offset: 2px;
}

a {
  color: var(--c-accent);
}
a:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 12px;
}
.table th, .table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--c-border);
}
.table th { color: var(--c-text-dim); font-weight: 500; font-size: 13px; }
.table tr:hover td { background: rgba(70, 200, 255, 0.05); }

/*
 * N-M-05 audit fix: scrollable wrapper for any <table class="table"> so
 * narrow viewports do not break the layout when the column count exceeds
 * the available width.
 *
 * NEW-M5-A audit fix (pass-5): на узких экранах .table-wrap получает
 * горизонтальный overflow, и без явной фокусировки клавиатурный
 * пользователь не мог его скроллить. Добавляем tabindex="0" + role=region
 * в шаблонах (publish.ejs / exhibits/list.ejs) и видимый :focus-visible
 * outline тут, чтобы фокус на контейнере был заметен и WCAG 2.1.1
 * (Keyboard) выполнялся.
 */
.table-wrap {
  width: 100%;
  overflow-x: auto;
}
.table-wrap:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.flash {
  padding: 12px 16px;
  border-radius: 6px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.flash-prefix {
  margin-right: 4px;
}
.flash-icon {
  display: inline-flex;
  align-items: center;
}
.flash-ok { background: rgba(107, 224, 154, 0.15); border: 1px solid var(--c-ok); color: var(--c-ok); }
.flash-err { background: rgba(255, 107, 107, 0.12); border: 1px solid var(--c-error); color: var(--c-error); }
/*
 * M-R6-04 (cycle-2-iter1-F3): жёлтый flash для частично-успешных
 * операций — например, аудио загружено, но WhisperX-выравнивание
 * не сработало. Зелёный flash в этом случае создавал ложное
 * ощущение успеха. Иконка-восклицание + слово «Внимание:» дают
 * non-color cue (SC 1.4.1). Контраст currentColor (#ffd17a) к
 * фоновой подложке `.callout-warn` ≈ 4.7:1 (SC 1.4.3). Сама
 * страничка `body` тёмно-синяя, на ней rgba(255,209,122,.08)
 * остаётся почти прозрачной — flash-text получает цвет
 * `--c-text` (см. правило ниже), которое держит 4.5:1.
 */
.flash-warn {
  background: rgba(255, 209, 122, 0.12);
  border: 1px solid var(--c-warn);
  color: var(--c-warn);
}
.flash-ok .flash-text,
.flash-err .flash-text,
.flash-warn .flash-text {
  color: var(--c-text);
}

.muted { color: var(--c-text-dim); }

.kv {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 8px 16px;
  margin: 8px 0;
}
.kv > dt {
  color: var(--c-text-dim);
}
.kv > dd {
  margin: 0;
}

.tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--c-accent-soft);
  font-size: 12px;
  color: var(--c-text);
}
.tag-ok { background: rgba(107, 224, 154, 0.2); color: var(--c-ok); }
.tag-warn { background: rgba(255, 200, 100, 0.2); color: var(--c-warn); }

.tag-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.tag-list li {
  margin: 0;
}

.empty-state {
  text-align: center;
  padding: 48px 24px;
  color: var(--c-text-dim);
}
.empty-state h2 {
  margin: 0 0 8px;
  color: var(--c-text);
}
/*
 * cycle-iter1-F2W2 (MED-R4-14): primary CTA внутри empty-state карточки.
 * Carbon Empty States pattern — «Direct the user to a primary action
 * button positioned underneath the copy». Кнопка ставится ПОД
 * объяснительным параграфом и центрируется заодно с заголовком и
 * подсказкой.
 */
.empty-state-cta {
  margin-top: 16px;
  display: inline-flex;
  gap: 8px;
}

/*
 * cycle-iter1-F2W2 (MED-R2-14): visual marker для пар, ссылающихся
 * на soft-deleted экспонат. Тёплый янтарный фон через --c-warn —
 * та же семантика, что у `.tag-warn`. На is-orphan-help (вторая
 * строка с подсказкой) фон чуть светлее, чтобы две строки
 * читались как один блок.
 */
.table tr.is-orphan > td {
  background: rgba(212, 167, 102, 0.10);
}
.table tr.is-orphan-help > td {
  background: rgba(212, 167, 102, 0.05);
  border-top: 0;
  padding-top: 0;
}
.table tr.is-orphan-help .help {
  margin: 0;
}

.validation-list {
  margin: 12px 0;
  padding-left: 20px;
}
.validation-list li {
  margin-bottom: 6px;
}
/*
 * NEW-min-1 (Block 5): ошибки валидации красные (--c-error), а не
 * жёлтые (--c-warn). Жёлтый сигнализирует «внимание», но не «нельзя
 * опубликовать»; ошибка валидации — это блокер, и цвет должен это
 * прямо передавать.
 */
.validation-list li.error {
  color: var(--c-error);
  font-weight: 600;
}
/*
 * BLE-9 (HIGH UX): warning-tone for non-blocking validation hints
 * --- partial RSSI override dropped, etc. Distinguishable from .error
 * (red/bold) and from plain list items (dark-blue).
 */
.validation-list li.warning {
  color: var(--c-warn);
  font-weight: 600;
}

.diff-list {
  margin: 12px 0;
  padding-left: 20px;
}
.diff-list li {
  margin-bottom: 6px;
}

/*
 * CSP-CRIT-B (pass-3) audit fix: replace 30+ inline `style=""` attributes in
 * EJS templates with named utility classes. The previous CSP without
 * `'unsafe-inline'` for `style-src` blocked every inline style and broke
 * the layout (heading top margins, button spacing, side-by-side forms,
 * monospaced code wrapping, the red "errors >0" tag in publish/preview).
 */
.h-flush { margin-top: 0; }
.mt-sm { margin-top: 12px; }
.mt-md { margin-top: 16px; }
.mt-lg { margin-top: 20px; }
.inline-form { display: inline; }
.nav-logout-form { display: inline; margin-left: 8px; }
.break-anywhere { overflow-wrap: anywhere; }
.code-sm { font-size: 12px; }

/*
 * Red error-count tag. NEW-min-2 (Block 5): повышаем контраст —
 * заполненный красный фон + светлый текст, чтобы chip-«ошибок»
 * был самым заметным элементом сводки. Раньше прозрачный fill
 * на тёмно-синем фоне делал tag-err тише, чем tag-ok / tag-warn.
 */
.tag-err {
  background: var(--c-error);
  color: #260000;
  font-weight: 700;
}

/*
 * N3-MIN-06 audit fix: respect prefers-reduced-motion on the skip-link
 * sliding-down animation.
 */
@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/* N-M-01: Russian field labels in the diff list render as small chips. */
.diff-field {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: rgba(70, 200, 255, 0.12);
  font-size: 13px;
  color: var(--c-accent);
}

.login-page {
  display: grid;
  place-items: center;
  min-height: 100vh;
}
.login-card {
  width: 380px;
  max-width: 92vw;
}

/*
 * UX-rewrite (curator-friendly redesign): hero state card, primary
 * action emphasis, lead/help paragraph hierarchy, and the technical-
 * details disclosure block. The collapsed `<details>` element is
 * keyboard-accessible by default, doesn't need JS, plays nice with
 * CSP, and signals «это для инженеров, можно пропустить» without
 * removing audit-trail value.
 */
.lead {
  font-size: 16px;
  line-height: 1.5;
  color: var(--c-text);
  margin: 8px 0 16px;
  max-width: 720px;
}
.help {
  font-size: 14px;
  line-height: 1.5;
  color: var(--c-text-dim);
  margin: 6px 0 12px;
  max-width: 720px;
}
.help-strong {
  color: var(--c-text);
}

.card-hero {
  background: linear-gradient(135deg, #195472 0%, #143f55 100%);
  border: 1px solid var(--c-accent-soft);
}
.card-hero .hero-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 12px;
  color: var(--c-text-dim);
  margin: 0 0 6px;
}
.card-hero .hero-value {
  font-size: 22px;
  font-weight: 600;
  color: var(--c-text);
  margin: 0 0 6px;
}
.card-hero .hero-meta {
  color: var(--c-text-dim);
  margin: 0;
  font-size: 14px;
}

.btn-primary-lg {
  font-size: 17px;
  padding: 14px 24px;
}

.callout {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 14px 16px;
  border-radius: 8px;
  margin: 12px 0;
}
.callout-warn {
  background: rgba(255, 209, 122, 0.10);
  border: 1px solid var(--c-warn);
}
.callout-warn .callout-title {
  color: var(--c-warn);
  font-weight: 600;
}
.callout-ok {
  background: rgba(107, 224, 154, 0.10);
  border: 1px solid var(--c-ok);
}
.callout-ok .callout-title {
  color: var(--c-ok);
  font-weight: 600;
}
.callout-text {
  color: var(--c-text);
  margin: 0;
}

.action-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.action-list li {
  margin: 0;
}
.action-list a {
  display: block;
  padding: 14px 16px;
  background: rgba(70, 200, 255, 0.06);
  border: 1px solid var(--c-border);
  border-radius: 8px;
  text-decoration: none;
}
.action-list a:hover {
  background: rgba(70, 200, 255, 0.12);
  border-color: var(--c-accent);
}
.action-list .action-title {
  display: block;
  color: var(--c-text);
  font-weight: 600;
  font-size: 16px;
}
.action-list .action-help {
  display: block;
  color: var(--c-text-dim);
  font-size: 13px;
  margin-top: 2px;
}

.tech-details {
  margin-top: 16px;
  border: 1px dashed var(--c-border);
  border-radius: 8px;
  padding: 0 14px;
  background: rgba(0, 0, 0, 0.10);
}
.tech-details > summary {
  list-style: none;
  cursor: pointer;
  padding: 12px 0;
  color: var(--c-text-dim);
  font-size: 14px;
  user-select: none;
}
.tech-details > summary::-webkit-details-marker { display: none; }
.tech-details > summary::before {
  content: '▸ ';
  color: var(--c-text-dim);
  display: inline-block;
  margin-right: 4px;
}
.tech-details[open] > summary::before {
  content: '▾ ';
}
.tech-details[open] > summary {
  border-bottom: 1px dashed var(--c-border);
  margin-bottom: 12px;
}
.tech-details > summary:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: 4px;
}
.tech-details .kv {
  margin: 0 0 12px;
}
.tech-details .help {
  margin-top: 0;
}

.help-link {
  display: block;
  margin-top: 16px;
  font-size: 13px;
  color: var(--c-text-dim);
}
.help-link a {
  color: var(--c-text-dim);
  text-decoration: underline;
}
.help-link a:hover {
  color: var(--c-accent);
}

.changes-list {
  list-style: none;
  margin: 12px 0;
  padding: 0;
}
.changes-list li {
  padding: 10px 12px;
  border-left: 3px solid var(--c-accent);
  background: rgba(70, 200, 255, 0.05);
  border-radius: 0 6px 6px 0;
  margin-bottom: 6px;
}
.changes-list .change-title {
  color: var(--c-text);
  font-weight: 600;
}
.changes-list .change-detail {
  color: var(--c-text-dim);
  font-size: 13px;
  display: block;
  margin-top: 2px;
}

.errors-list {
  list-style: none;
  margin: 12px 0;
  padding: 0;
}
.errors-list li {
  padding: 10px 12px;
  border-left: 3px solid var(--c-error);
  background: rgba(255, 107, 107, 0.08);
  border-radius: 0 6px 6px 0;
  margin-bottom: 6px;
  color: var(--c-text);
}

/*
 * Phase A.1: pre-блок для иллюстрации форматов CSV / markdown в
 * UI-инструкциях. Без inline-style, потому что CSP запрещает.
 */
.code-block-csv,
.code-block-md {
  background: rgba(0, 0, 0, 0.2);
  padding: 12px;
  border-radius: 6px;
  overflow-x: auto;
  margin: 8px 0;
  white-space: pre;
  color: var(--c-text);
}

/*
 * Phase A.1: дополнительная навигация для админки. Подкласс .nav-aux
 * горизонтальная полоска под основной нав-баром (используется для ссылок
 * Маяки / Корзина и т.п. под пунктом «Экспонаты»). Опционально
 * (см. _nav.ejs).
 */
.nav a.active {
  color: var(--c-accent);
  font-weight: 600;
}

/*
 * Phase A.1: side-by-side preview для markdown-textarea на странице
 * редактирования экспоната. На широких экранах textarea и preview
 * стоят рядом; на узких — друг под другом.
 */
.md-editor {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  align-items: stretch;
}
.md-editor textarea {
  min-height: 220px;
  font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
  font-size: 14px;
  line-height: 1.5;
}
.md-preview {
  background: rgba(0, 0, 0, 0.15);
  border: 1px solid var(--c-border);
  border-radius: 6px;
  padding: 12px 14px;
  min-height: 220px;
  overflow-y: auto;
  color: var(--c-text);
}
.md-preview h1, .md-preview h2, .md-preview h3 {
  color: var(--c-text);
  margin: 12px 0 6px;
}
.md-preview p { margin: 6px 0; }
.md-preview ul, .md-preview ol { margin: 6px 0 6px 18px; }
.md-preview a { color: var(--c-accent); }
.md-preview code {
  background: rgba(0, 0, 0, 0.25);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 90%;
}
.md-preview-empty {
  color: var(--c-text-dim);
  font-style: italic;
}
@media (max-width: 768px) {
  .md-editor { grid-template-columns: 1fr; }
}

/*
 * Phase A.1 audit fix A11Y-2 — checkbox-group для соседей.
 * <select multiple> заменён на fieldset со списком чекбоксов:
 * куратор отмечает соседей по одному без Ctrl-click, screen reader
 * читает список как нативный, состояние видно сразу.
 */
.neighbours-group {
  border: 1px solid var(--c-border);
  border-radius: 6px;
  padding: 12px 16px;
  margin: 8px 0;
}
.neighbours-group legend {
  padding: 0 6px;
  font-weight: 600;
}

/*
 * cycle-iter1-F2 (HIGH-R5-06): sponsorship-group — fieldset вокруг
 * связанной группы спонсорских полей внутри <details class="tech-details">.
 * Внешняя обводка не нужна (родительский <details> уже даёт рамку);
 * только сбрасываем браузерный default border, чтобы не было
 * border-on-border. Legend визуально скрыт, но остаётся для AT.
 */
.sponsorship-group {
  border: 0;
  margin: 0;
  padding: 0;
}

/*
 * cycle-iter1-F2W2 (MED-R4-16): pair-group — fieldset вокруг двух
 * select'ов «От экспоната» / «К экспонату» на bridges/pairs/edit.ejs.
 * Семантически это одна логическая «пара» (WCAG 1.3.1 Info and
 * Relationships); визуально оборачиваем рамкой как у
 * `.neighbours-group`, чтобы куратор видел принадлежность select'ов
 * одной группе.
 */
.pair-group {
  border: 1px solid var(--c-border);
  border-radius: 6px;
  padding: 12px 16px;
  margin: 8px 0;
}
.pair-group legend {
  padding: 0 6px;
  font-weight: 600;
}

/*
 * cycle-iter2-F2W3 (MED-R4-29): orphan-form-body — внешний
 * <fieldset disabled>, который оборачивает все четыре карточки
 * формы pairs/edit.ejs, когда переход ссылается на soft-deleted
 * экспонат. HTML-disabled на fieldset распространяется на все
 * вложенные form-controls (включая submit), но визуально мы НЕ
 * хотим вторую рамку поверх карточек — обводку и padding
 * сбрасываем. Само orphan-состояние уже сообщается через
 * callout-warn выше формы.
 */
.orphan-form-body {
  border: 0;
  margin: 0;
  padding: 0;
  min-inline-size: 0;
}
.neighbours-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 6px 16px;
}
.checkbox-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  cursor: pointer;
}
.checkbox-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}

/*
 * Phase A.1 audit fix UX-1 — busy state для submit-кнопок при
 * длинных аплоадах. focus-restorer.js навешивает aria-busy и
 * is-busy class когда форма submitted; CSS показывает spinner и
 * disabled-облик, чтобы куратор не нажимал submit повторно.
 */
.btn[aria-busy="true"],
.btn.is-busy {
  cursor: progress;
  opacity: 0.7;
}
.btn.is-busy::before {
  content: "";
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 6px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: btn-spin 0.8s linear infinite;
  vertical-align: -2px;
}
@keyframes btn-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .btn.is-busy::before { animation: none; }
}

/*
 * Phase A.1: поле «текущий медиа-файл» на странице редактирования
 * экспоната — небольшая карточка с именем файла + ссылкой «послушать»
 * / «открыть». Если медиа не загружен — мутный плейсхолдер.
 */
.media-current {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 10px 12px;
  background: rgba(0, 0, 0, 0.15);
  border: 1px solid var(--c-border);
  border-radius: 6px;
  margin: 4px 0 8px;
}
.media-current .media-meta {
  flex: 1;
  font-size: 13px;
  color: var(--c-text-dim);
}
.media-current code {
  font-size: 12px;
}
/*
 * HIGH-R6-02 (cycle-2-iter1-F3): inline-проигрыватель рядом с
 * именем файла. Растягиваем на всю ширину карточки, чтобы native
 * controls оставались usable и на узких экранах. На мобильных
 * (<480px) строка с code и аудио-плеером выравнивается в колонку.
 * preload="none" — клиппинг трафика, пока куратор не нажал Play.
 */
.media-audio {
  flex-basis: 100%;
  width: 100%;
  margin-top: 4px;
  height: 36px;
  border-radius: 6px;
}
.media-audio:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}
@media (max-width: 480px) {
  .media-audio { height: 40px; }
}

/*
 * Phase A.1: красная зона удаления — отдельная карточка с акцентом.
 */
.danger-zone {
  border: 1px solid var(--c-error);
  background: rgba(255, 107, 107, 0.06);
}
.danger-zone h2 {
  color: var(--c-error);
}


@media (max-width: 768px) {
  .container { padding: 12px; }
  .nav {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  .kv { grid-template-columns: 1fr; }
  .table-wrap { overflow-x: auto; }
}
@media (max-width: 480px) {
  body { font-size: 15px; }
  .table { font-size: 14px; }
}

/* ============================================================
 * UX-pass-2026-05 (research-driven, single big pass)
 * ----------------------------------------------------------------
 * Five improvements added in this pass:
 *   1. List search/filter (?q= SSR + JS instant-filter enhancement)
 *   2. Form draft autosave + unsaved-changes guard
 *   3. Section navigation (sticky TOC) on long edit form
 *   4. Last-modified info on edit pages
 *   5. Discoverable keyboard shortcuts (/, n, ?, Esc) + help <dialog>
 * Each rule below is namespaced to its feature so future passes can
 * remove blocks atomically.
 * ============================================================
 */

/* ---- 1. Search bar above tables ------------------------------ */
.list-search {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 0 0 12px;
}
.list-search label {
  margin: 0;
  flex: 1 1 280px;
  min-width: 0;
}
.list-search input[type="search"] {
  width: 100%;
  padding: 10px 12px;
  background: var(--c-bg);
  border: 1px solid var(--c-border);
  border-radius: 6px;
  color: var(--c-text);
  font-size: 15px;
  margin-top: 4px;
}
.list-search input[type="search"]:focus,
.list-search input[type="search"]:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 1px;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 2px rgba(70, 200, 255, 0.2);
}
.list-search .btn {
  margin-top: 4px;
}
.list-summary {
  font-size: 13px;
  color: var(--c-text-dim);
  margin: 6px 0 12px;
  font-variant-numeric: tabular-nums;
}
.list-summary .list-summary-strong {
  color: var(--c-text);
  font-weight: 600;
}
/* Скрыть строку, если js-фильтр пометил её. Без !important — серверный
 * рендер (no-JS) показывает все строки, JS сам управляет атрибутом. */
.table tbody tr[hidden] {
  display: none;
}

/* ---- 2. Draft autosave indicator ------------------------------ */
.draft-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  background: rgba(70, 200, 255, 0.1);
  border: 1px solid var(--c-accent-soft);
  color: var(--c-text-dim);
  font-variant-numeric: tabular-nums;
  /* Мягкое появление при первом write'е без attention-grabbing motion */
  transition: opacity 0.2s ease;
}
.draft-pill[data-state="saving"] { color: var(--c-text-dim); }
.draft-pill[data-state="saved"] { color: var(--c-ok); border-color: var(--c-ok); }
.draft-pill[data-state="restored"] { color: var(--c-warn); border-color: var(--c-warn); }
.draft-pill[hidden] { display: none; }
.draft-restore-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 10px 12px;
  margin: 0 0 12px;
  border-radius: 8px;
  background: rgba(255, 209, 122, 0.10);
  border: 1px solid var(--c-warn);
}
.draft-restore-bar .draft-restore-text {
  flex: 1 1 280px;
  color: var(--c-text);
  font-size: 14px;
  margin: 0;
}
@media (prefers-reduced-motion: reduce) {
  .draft-pill { transition: none; }
}

/* ---- 3. Section navigation on edit form ---------------------- */
.edit-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 24px;
  align-items: start;
}
.edit-toc {
  position: sticky;
  top: 12px;
  margin: 0;
  padding: 12px;
  list-style: none;
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid var(--c-border);
  border-radius: 8px;
  font-size: 14px;
  max-height: calc(100vh - 24px);
  overflow-y: auto;
}
.edit-toc li { margin: 0; }
.edit-toc a {
  display: block;
  padding: 6px 10px;
  border-left: 3px solid transparent;
  color: var(--c-text-dim);
  text-decoration: none;
  border-radius: 0 4px 4px 0;
}
.edit-toc a:hover {
  color: var(--c-text);
  background: rgba(70, 200, 255, 0.06);
}
.edit-toc a:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
}
.edit-toc a[aria-current="true"] {
  color: var(--c-accent);
  background: rgba(70, 200, 255, 0.10);
  border-left-color: var(--c-accent);
}
.edit-toc-title {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 11px;
  color: var(--c-text-dim);
  margin: 0 0 8px;
  padding-left: 10px;
}
.edit-content {
  /* Anchor-target offset: при переходе по #section-… заголовок не
   * прячется под скроллом, а отступает на 12px от верха. */
  scroll-margin-top: 16px;
}
.edit-content > .card {
  scroll-margin-top: 16px;
}
@media (max-width: 980px) {
  .edit-layout { grid-template-columns: 1fr; }
  .edit-toc {
    position: static;
    max-height: none;
    margin: 0 0 12px;
  }
}

/* ---- 4. Last-modified meta line ------------------------------- */
.meta-line {
  font-size: 13px;
  color: var(--c-text-dim);
  margin: 4px 0 12px;
  padding: 6px 10px;
  background: rgba(0, 0, 0, 0.12);
  border-radius: 6px;
  display: inline-block;
}
.meta-line strong {
  color: var(--c-text);
  font-weight: 600;
}

/* ---- 5. Keyboard hint chips + help dialog -------------------- */
kbd, .kbd {
  display: inline-block;
  padding: 2px 6px;
  font-family: ui-monospace, "Cascadia Code", "Consolas", monospace;
  font-size: 12px;
  line-height: 1;
  color: var(--c-text);
  background: rgba(0, 0, 0, 0.30);
  border: 1px solid var(--c-border);
  border-bottom-width: 2px;
  border-radius: 4px;
  vertical-align: 1px;
  font-variant-numeric: tabular-nums;
}
.kbd-hint {
  font-size: 12px;
  color: var(--c-text-dim);
  margin: 4px 0 0;
}
.kbd-hint kbd { margin: 0 2px; }

dialog.help-dialog {
  border: 1px solid var(--c-border);
  border-radius: 10px;
  background: var(--c-card);
  color: var(--c-text);
  padding: 0;
  max-width: 560px;
  width: 92vw;
}
dialog.help-dialog::backdrop {
  background: rgba(0, 16, 32, 0.55);
}
.help-dialog-body {
  padding: 24px;
}
.help-dialog-body h2 {
  margin: 0 0 12px;
}
.help-dialog-body dl {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 8px 16px;
  margin: 12px 0;
}
.help-dialog-body dt {
  text-align: right;
}
.help-dialog-body dd {
  margin: 0;
  color: var(--c-text-dim);
}
.help-dialog-body .help-dialog-actions {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.help-trigger-link {
  font-size: 12px;
  color: var(--c-text-dim);
  text-decoration: underline dotted;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
}
.help-trigger-link:hover { color: var(--c-accent); }
.help-trigger-link:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Sticky table headers — небольшая помощь куратору при пролистывании
 * длинных списков. Работает поверх .table-wrap, не ломая overflow-x.
 */
.table thead th {
  position: sticky;
  top: 0;
  background: var(--c-card);
  z-index: 1;
}

/* ============================================================
 * Visual polish 2026-05-20 — calm marine direction
 * ----------------------------------------------------------------
 * Куратор сказал: «вижу обновления, но визуально хочется больше».
 * Этот pass — НЕ переделка структуры (структура работает после 13
 * раундов аудитов), а единичный визуальный проход, выбравший одно
 * направление вместо «всего понемногу».
 *
 * Из трёх кандидатов (editorial / calm-marine / brutalist-clean
 * Russian) выбран calm-marine, потому что домен — Музей Мирового
 * океана — буквально И ЕСТЬ визуальный словарь. Глубокая вода,
 * приглушённые бирюзово-синие, мягкое движение света сверху вниз.
 *
 * Конкретные изменения:
 *   - Палитра углублена: муторная неоново-голубая `#46c8ff` заменена
 *     на приглушённый океанографический бирюзовый `#5ab9c9`. Bg
 *     заглублён с `#0b2a3a` до `#081e2a`. Появилась 4-уровневая
 *     ритмика поверхностей (bg → surface-1 → surface-2 → surface-3)
 *     вместо текущей 2-уровневой (bg → card).
 *   - Бордеры: hairline rgba(180,215,230,0.07) вместо плотных
 *     «вырезанных» линий `--c-border: #1f5570`. Карточки больше не
 *     читаются как отдельные коробки на странице.
 *   - Hero card: ОДИН низкоамплитудный radial-gradient в правом
 *     верхнем углу, имитирующий «свет сверху сквозь воду». НЕ
 *     диагональный 135deg голубой градиент (был AI-slop tell).
 *   - Headings: weight 600 (было 700), tighter letter-spacing.
 *     Кириллица на 700 визуально утолщает «ША», 600 на ней мягче.
 *   - Lead paragraph: 17px / 1.6 — куратор работает часовыми
 *     сессиями вечером, чуть больше воздуха в строках.
 *   - Micro-interactions: 150ms ease-out на :hover для .btn и
 *     .action-list. Сдвиг translateY(-1px), не «bouncy» 4px-jump.
 *   - Один декоративный ocean-divider — тонкая SVG-волна 12px
 *     высоты под h1 на /dashboard и /publish. Низкий контраст
 *     (opacity 0.7 на и без того низко-контрастном stroke 0.32),
 *     помечает страницу как «World Ocean» без крика «underwater».
 *   - Удалена эмодзи 📝 из meta-line — единственная эмодзи в EJS,
 *     ясный AI-slop tell.
 *
 * AI-slop antipatterns, КОТОРЫЕ НЕ ПРИМЕНЕНЫ (по списку из brief):
 *   - Радужные градиенты purple→blue→pink на CTA — нет, единственный
 *     gradient это near-monochrome radial в hero.
 *   - Glassmorphism backdrop-filter blur на каждой карточке — нет,
 *     только opaque surfaces + hairline borders.
 *   - Симметричные «hero сетки 2×2» — нет, layout остался
 *     асимметричным (TOC слева, контент справа на edit-страницах).
 *   - «Get started for free» / «Built with X» badges — нет, это
 *     внутренняя админка, не landing.
 *   - Inter / Geist шрифт-стек — нет, system stack с Segoe UI первым
 *     для русской аудитории на Windows.
 *   - 3D «liquid» SVG blobs — нет.
 *   - Gradient-text на заголовках — нет, plain цвет.
 *   - Centered everything — нет, иерархия слева направо сохранена.
 *   - Эмодзи в заголовках разделов — нет (была одна 📝, удалена).
 *   - «Loading... ✨» — нет, нормальный spinner на .btn[is-busy].
 *   - Пастельная OpenAI-clone палитра — нет, deep saturated marine.
 * ============================================================
 */
:root {
  /* Поверхности — четырёх-уровневая ритмика. Каждая ступень едва
   * заметнее предыдущей; вместе они создают глубину без elevation. */
  --c-bg: #081e2a;
  --c-bg-alt: #0a2434;
  --c-surface-1: #0f2c3d;
  --c-surface-2: #143a4d;
  --c-surface-3: #1a4658;

  /* Текст */
  --c-text: #e6f0f5;
  --c-text-dim: #88a6b6;
  /*
   * cycle-iter1-F2W2 (MED-R5-09): WCAG 1.4.3 contrast audit показал,
   * что прежний #5b7886 даёт всего 2.56:1 на surface-2 (#143a4d) —
   * это failure для normal text (порог 4.5:1) и даже для large
   * (3:1). Брифом-указанный #7693a3 тоже не проходит (3.72:1 на
   * surface-2 — проверено WebAIM API). Ставим #85a8b7 — проверено
   * против всех четырёх поверхностей (surface-2, surface-1,
   * bg-alt, bg): 4.75 / 5.72 / 6.30 / 6.74 — все ≥ 4.5:1, AA pass.
   * Тон сохраняет холодную «calm-marine» характеристику.
   */
  --c-text-mute: #85a8b7;

  /* Backwards-compat: старая `--c-card` всё ещё ссылается на
   * `surface-2` для правил, которые мы не переопределяем. */
  --c-card: var(--c-surface-2);

  /* Акцент: приглушённый океанографический бирюзовый.
   * Контраст #5ab9c9 на #081e2a ≈ 6.4:1 — WCAG AA для non-text UI. */
  --c-accent: #5ab9c9;
  --c-accent-strong: #7fcfdc;
  --c-accent-soft: #1d4757;
  --c-accent-glow: rgba(90, 185, 201, 0.16);

  /* Бордеры — hairline rgba поверх любой поверхности */
  --c-border: rgba(180, 215, 230, 0.07);
  --c-border-strong: rgba(180, 215, 230, 0.13);

  /* Семантика — менее неоновая, чем раньше */
  --c-error: #d96763;
  --c-ok: #6fc591;
  --c-warn: #d4a766;

  /* Тени — почти неосязаемые */
  --shadow-sm: 0 1px 0 rgba(0, 0, 0, 0.25);
  --shadow-md: 0 2px 10px -4px rgba(0, 0, 0, 0.45);
}

/* Body bg остаётся 180deg gradient (signal «depth»), но на новых
 * заглублённых тонах. */
body {
  background: linear-gradient(180deg, var(--c-bg) 0%, var(--c-bg-alt) 100%);
  /* Tabular nums в metadata + audit timestamps — чтобы цифры в
   * соседних строках выравнивались по колонке. */
  font-feature-settings: "tnum";
}

/* ---- Headings -------------------------------------------------- */
h1 {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
h1.brand {
  font-size: 20px;
  font-weight: 600;
  letter-spacing: 0.005em;
}
h2 {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.003em;
  line-height: 1.3;
}

.brand {
  font-weight: 600;
  letter-spacing: 0.005em;
}
.brand-sub {
  color: var(--c-text-mute);
}

/* ---- Lead paragraph (чуть больше воздуха) ---------------------- */
.lead {
  font-size: 17px;
  line-height: 1.6;
  color: var(--c-text);
  max-width: 70ch;
}

/* ---- Nav (hairline-low, не «панель в шапке») ------------------- */
.nav {
  background: var(--c-bg-alt);
  border-bottom: 1px solid var(--c-border-strong);
  padding: 14px 24px;
}

/* ---- Cards (hairline + еле уловимая тень) ---------------------- */
.card {
  background: var(--c-surface-2);
  border: 1px solid var(--c-border);
  border-radius: 8px;
  box-shadow: var(--shadow-sm);
}

/* Hero card: один низкоамплитудный radial gradient. Имитирует
 * «свет сверху сквозь воду» — domain-appropriate, не AI 135deg. */
.card-hero {
  background:
    radial-gradient(
      ellipse 80% 55% at 78% -15%,
      rgba(127, 207, 220, 0.10) 0%,
      rgba(127, 207, 220, 0.00) 65%
    ),
    var(--c-surface-2);
  border: 1px solid var(--c-border-strong);
  box-shadow: var(--shadow-md);
}
.card-hero .hero-label {
  color: var(--c-text-mute);
  font-size: 11px;
  letter-spacing: 0.10em;
}
.card-hero .hero-value {
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.005em;
}
.card-hero .hero-meta {
  font-size: 14px;
  color: var(--c-text-dim);
  max-width: 60ch;
}

/* ---- Buttons (muted accent + soft micro-interaction) ----------- */
.btn {
  background: var(--c-accent);
  color: #082024;
  font-weight: 600;
  border-radius: 6px;
  transition: background-color 150ms ease-out, transform 150ms ease-out;
}
.btn:hover {
  background: var(--c-accent-strong);
  transform: translateY(-1px);
}
.btn:active {
  transform: translateY(0);
}
.btn-secondary {
  background: var(--c-surface-3);
  color: var(--c-text);
  border: 1px solid var(--c-border-strong);
}
.btn-secondary:hover {
  background: #235468;
  transform: translateY(-1px);
}
.btn-danger {
  background: var(--c-error);
  color: #2a0a0a;
}
.btn-danger:hover {
  background: #e57b77;
  transform: translateY(-1px);
}
.btn-primary-lg {
  font-size: 16px;
  padding: 13px 22px;
  letter-spacing: 0.005em;
}
@media (prefers-reduced-motion: reduce) {
  .btn,
  .btn:hover,
  .btn-secondary,
  .btn-secondary:hover,
  .btn-danger:hover {
    transition: none;
    transform: none;
  }
}

/* ---- Inputs ---------------------------------------------------- */
input[type="text"],
input[type="password"],
input[type="search"],
input[type="number"],
input[type="datetime-local"],
input[type="file"],
textarea,
select,
.list-search input[type="search"] {
  background: var(--c-bg);
  border: 1px solid var(--c-border-strong);
  border-radius: 5px;
}
input:focus, textarea:focus, select:focus,
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--c-accent);
  outline-offset: 1px;
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-glow);
}

/* ---- Tables ---------------------------------------------------- */
.table thead th {
  background: var(--c-surface-1);
  color: var(--c-text-mute);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.table th, .table td {
  border-bottom: 1px solid var(--c-border);
}
.table tr:hover td { background: var(--c-accent-glow); }

/* ---- Action-list (dashboard cards) ----------------------------- */
.action-list a {
  background: var(--c-surface-1);
  border: 1px solid var(--c-border);
  border-radius: 6px;
  transition:
    background-color 150ms ease-out,
    border-color 150ms ease-out,
    transform 150ms ease-out;
}
.action-list a:hover {
  background: var(--c-surface-3);
  border-color: var(--c-border-strong);
  transform: translateY(-1px);
}
.action-list .action-help {
  color: var(--c-text-mute);
}
@media (prefers-reduced-motion: reduce) {
  .action-list a { transition: none; }
  .action-list a:hover { transform: none; }
}

/* ---- Callouts (softer fills + softer borders) ------------------ */
.callout-warn {
  background: rgba(212, 167, 102, 0.08);
  border-color: rgba(212, 167, 102, 0.45);
}
.callout-warn .callout-title { color: var(--c-warn); }
.callout-ok {
  background: rgba(111, 197, 145, 0.07);
  border-color: rgba(111, 197, 145, 0.45);
}
.callout-ok .callout-title { color: var(--c-ok); }

/* ---- Changes / errors lists ------------------------------------ */
.changes-list li {
  background: var(--c-surface-1);
  border-left-color: var(--c-accent);
  border-radius: 0 5px 5px 0;
}
.errors-list li {
  background: rgba(217, 103, 99, 0.07);
  border-left-color: var(--c-error);
}

/* ---- Tech-details (solid hairline, не пунктирная) -------------- */
.tech-details {
  border: 1px solid var(--c-border);
  border-radius: 6px;
  background: var(--c-surface-1);
}
.tech-details > summary {
  color: var(--c-text-mute);
  font-size: 13px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.tech-details[open] > summary {
  border-bottom: 1px solid var(--c-border);
}

/* ---- Tags ------------------------------------------------------ */
.tag {
  background: var(--c-accent-soft);
  border: 1px solid var(--c-border-strong);
  color: var(--c-text);
}
.diff-field {
  background: var(--c-accent-glow);
  color: var(--c-accent-strong);
  font-size: 12px;
  letter-spacing: 0.005em;
}

/* ---- Meta-line (audit footprint, без эмодзи) ------------------- */
.meta-line {
  display: block;
  background: transparent;
  border-left: 2px solid var(--c-accent-soft);
  padding: 4px 12px;
  border-radius: 0;
  color: var(--c-text-dim);
  font-size: 13px;
  margin: 4px 0 16px;
}

/* ---- Edit-toc (sticky sidebar) --------------------------------- */
.edit-toc {
  background: var(--c-surface-1);
  border: 1px solid var(--c-border);
  border-radius: 6px;
}
.edit-toc-title { color: var(--c-text-mute); }
.edit-toc a[aria-current="true"] {
  color: var(--c-accent-strong);
  background: var(--c-accent-glow);
  border-left-color: var(--c-accent);
}

/* ---- Draft-pill (less attention-grabbing) ---------------------- */
.draft-pill {
  background: transparent;
  border: 1px solid var(--c-border-strong);
}
.draft-pill[data-state="saved"] {
  border-color: rgba(111, 197, 145, 0.45);
  color: var(--c-ok);
}
.draft-pill[data-state="restored"] {
  border-color: rgba(212, 167, 102, 0.45);
  color: var(--c-warn);
}

/* ---- kbd (paper-key, без glassmorphism) ------------------------ */
kbd, .kbd {
  background: var(--c-surface-1);
  border: 1px solid var(--c-border-strong);
  border-bottom-width: 2px;
  font-size: 11px;
  padding: 2px 7px;
}

/* ---- Flash (нейтральнее, без рябиющего фона) ------------------- */
.flash-ok {
  background: rgba(111, 197, 145, 0.08);
  border-color: rgba(111, 197, 145, 0.45);
  color: var(--c-ok);
}
.flash-err {
  background: rgba(217, 103, 99, 0.08);
  border-color: rgba(217, 103, 99, 0.5);
  color: var(--c-error);
}

/* ---- Skip-link --------------------------------------------------*/
.skip-link {
  background: var(--c-accent);
  color: #082024;
  font-weight: 600;
  border-radius: 5px;
}

/* ---- list-summary (показано N из M) ---------------------------- */
.list-summary {
  color: var(--c-text-mute);
}
.list-summary .list-summary-strong {
  color: var(--c-text);
}

/* ----------------------------------------------------------------
 * Декоративный hairline-разделитель «волна».
 * Ставится точечно на dashboard и publish прямо после <h1>+lead;
 * 12px высоты, низкий контраст (stroke-opacity 0.32 × element
 * opacity 0.7 ≈ effective 22% поверх surface), не отвлекает,
 * но помечает страницу как «Музей Мирового океана».
 *
 * SVG как data: URI работает под CSP `img-src 'self' data:`.
 * Без анимаций (бережёт старшие ноутбуки куратора).
 * ---------------------------------------------------------------- */
.ocean-divider {
  display: block;
  height: 14px;
  margin: 4px 0 20px;
  border: 0;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 14' preserveAspectRatio='none'><path d='M0 7 Q 75 2 150 7 T 300 7 T 450 7 T 600 7 T 750 7 T 900 7 T 1050 7 T 1200 7' stroke='%237fcfdc' stroke-width='1' stroke-opacity='0.32' fill='none' /></svg>");
  opacity: 0.7;
  pointer-events: none;
}

/* ---- Field labels (чуть «суше», как в editorial-журнале) ------- */
label {
  color: var(--c-text-mute);
  font-size: 13px;
  letter-spacing: 0.005em;
}

/* ---- Legacy override: было `var(--c-card)` солидный --c-card.
 *      Sticky thead уже использует --c-card; сейчас это alias на
 *      --c-surface-2. Перекрываем, чтобы у sticky thead был именно
 *      surface-1 (тот же оттенок, что и у не-sticky thead-th
 *      выше — иначе при скролле граница «прыгает»). */
.table thead th {
  background: var(--c-surface-1);
}

/* ---- Cascade fixes: правила с большей специфичностью, которые
 *      использовали старую неоновую `rgba(70,200,255,...)` напрямую,
 *      и поэтому бы пробивались сквозь общий override блок. */
.list-search input[type="search"]:focus,
.list-search input[type="search"]:focus-visible {
  box-shadow: 0 0 0 3px var(--c-accent-glow);
}
.edit-toc a:hover {
  background: var(--c-accent-glow);
  color: var(--c-text);
}
