/* main.css — компоненти (DESIGN.md). Потрібен tokens.css. */
*{box-sizing:border-box;margin:0;padding:0}
  body{font-family:var(--font-body);background:var(--bg);color:var(--ink);font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased}
  a{color:inherit;text-decoration:none}
  button{font-family:inherit;cursor:pointer;border:none;background:none}
  ::selection{background:var(--accent-soft);color:#2a338a}
  .mono{font-family:var(--font-mono)}
  svg.i{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex:none}

  .app{display:grid;grid-template-columns:var(--rail-w) 1fr;min-height:100vh}

  /* rail */
  .rail{position:sticky;top:0;height:100vh;background:var(--rail-bg);display:flex;flex-direction:column;border-right:1px solid var(--rail-line);z-index:40}
  .rail__brand{display:flex;align-items:center;gap:10px;padding:18px 16px 14px}
  .rail__mark{width:30px;height:30px;border-radius:8px;flex:none;background:linear-gradient(150deg,#8ea6ff,#4a5abf);display:grid;place-items:center;color:#fff;font-family:var(--font-display);font-weight:700;font-size:16px}
  /* Знак-логотип: емблема має синю заливку #00408D, майже нерозрізненну на тлі
     рельса (--rail-bg #222a52), тому чип білий, а не градієнтний. Ширший за
     квадратний, бо емблема горизонтальна (341×229) і в 30px губиться. */
  .rail__mark--img{width:40px;background:#fff;padding:3px}
  .rail__mark--img img{width:100%;height:100%;object-fit:contain;display:block}
  .rail__name{font-family:var(--font-display);font-weight:600;font-size:14px;color:#f2f3f6;line-height:1.15}
  .rail__name span{display:block;font-family:var(--font-mono);font-weight:400;font-size:10px;color:var(--rail-dim);margin-top:2px}
  /* Угорі було ще моно-підпис «Розділи» (.rail__label); знято 9 жовтня 2026 —
     він називав очевидне, бо під ним і так самі лише розділи. Разом із ним
     пішли ~31px, які він займав, тож верхній відступ побільшав із 6px до 14px:
     інакше перший пункт меню підпирав би назву інституту. */
  .rail__scroll{flex:1;overflow-y:auto;padding:14px 12px 12px}
  .rail__scroll::-webkit-scrollbar{width:0}
  .nav{display:flex;align-items:center;gap:11px;width:100%;text-align:left;padding:9px 10px;border-radius:9px;color:var(--rail-txt);font-size:13.5px;font-weight:450;transition:background .14s,color .14s;position:relative}
  .nav svg.i{font-size:17px;color:var(--rail-dim);transition:color .14s}
  .nav:hover{background:#2b3566;color:#eef0f3}
  .nav:hover svg.i{color:#aab0d8}
  .nav.is-active{background:var(--rail-active);color:#fff}
  .nav.is-active svg.i{color:var(--accent-2)}
  .nav.is-active::before{content:"";position:absolute;left:-12px;top:50%;transform:translateY(-50%);width:3px;height:18px;border-radius:0 3px 3px 0;background:var(--accent-2)}
  .rail__foot{border-top:1px solid var(--rail-line);padding:11px 20px;display:flex;align-items:center;justify-content:space-between}
  .lang{display:flex;gap:3px;font-family:var(--font-mono);font-size:11.5px}
  .lang b{color:#fff;font-weight:500;padding:1px 6px;border-radius:5px;background:#33407a}
  .lang a{color:var(--rail-dim);padding:1px 6px}
  .rail__foot .soc a{color:var(--rail-dim);font-size:17px}
  .rail__foot .soc a:hover{color:#fff}

  /* main */
  .main{min-width:0;display:flex;flex-direction:column}
  .topbar{position:sticky;top:0;z-index:30;background:rgba(255,255,255,.85);backdrop-filter:saturate(1.6) blur(10px);border-bottom:1px solid var(--line);display:flex;align-items:center;gap:12px;padding:11px 26px}
  .burger{display:none;color:var(--ink-2);font-size:22px;padding:2px}
  .search{flex:1;max-width:440px;display:flex;align-items:center;gap:9px;background:var(--surface);border:1px solid transparent;border-radius:10px;padding:8px 12px;transition:border-color .14s,background .14s}
  .search:focus-within{background:#fff;border-color:var(--accent)}
  .search svg.i{font-size:16px;color:var(--ink-4)}
  .search input{border:none;outline:none;background:none;flex:1;font-size:13.5px;color:var(--ink);font-family:inherit}
  .search input::placeholder{color:var(--ink-4)}
  .search kbd{font-family:var(--font-mono);font-size:10px;color:var(--ink-4);border:1px solid var(--line-2);border-radius:5px;padding:2px 6px;background:#fff}
  /* .topbar__spacer і .avatar прибрані разом із самим аватаром: розпірка
     існувала тільки щоб відтиснути його вправо. Пошук лишається ліворуч і
     без неї — його ширину тримає max-width, а не сусід. */

  .scroll{overflow-y:auto}
  /* Колонка притиснута до рельса, а не відцентрована. Центрування лишало на
     широкому екрані по ~365px порожнечі з кожного боку, причому topbar у
     колонку не входить (у нього власний padding:26px) — пошук стояв ліворуч,
     а вміст починався на третину екрана правіше, і розбіжність читалася як
     помилка. Тепер обидва починаються з тих самих 26px. */
  /* Межа 1240px, а не 940px, і без окремого breakpoint: до ~1490px колонка
     однаково впирається в доступну ширину, тож умова лише додала б стрибок
     на 300px у точці перемикання. Прозі ширша колонка нічого не міняє — у
     .lead, .para і .prose власні обмеження рядка; ширшають сітки, картки,
     стрічка новин і бібліографічні рядки, тобто те, що від ширини виграє. */
  .wrap{max-width:1240px;margin:0;padding:32px 26px 72px;width:100%}
  .view{display:block}
  @keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

  .crumb{font-family:var(--font-mono);font-size:11px;color:var(--ink-4);display:flex;align-items:center;gap:7px;margin-bottom:14px;flex-wrap:wrap}
  .crumb a:hover{color:var(--accent)}
  .crumb svg.i{font-size:13px}
  .eyebrow{font-family:var(--font-mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--accent);font-weight:500}
  h1.h{font-family:var(--font-display);font-weight:600;font-size:31px;letter-spacing:-.01em;line-height:1.14;color:var(--ink);margin:10px 0 0}
  .lead{color:var(--ink-2);font-size:16px;line-height:1.6;margin-top:12px;max-width:640px}
  h2.s{font-family:var(--font-display);font-weight:600;font-size:19px;letter-spacing:-.01em;color:var(--ink);margin:34px 0 4px;display:flex;align-items:center;gap:9px}
  h2.s svg.i{font-size:18px;color:var(--accent)}
  .sub{color:var(--ink-3);font-size:13.5px;margin-bottom:14px}
  p.para{color:var(--ink-2);font-size:14.5px;line-height:1.7;margin-top:10px;max-width:680px}
  /* Посилання в абзаці — знову те саме, що з `.panel p a`: глобально
     `a{color:inherit}`, тож без цього правила посилання «Про серію…» на
     /publications/ виглядало б звичайним чорним текстом і його ніхто б не
     натиснув. Знайдено в браузері, а не в розмітці (DESIGN.md §8). */
  p.para a{color:var(--accent)}
  p.para a:hover{color:var(--ink)}

  /* .prose — текст новини, єдине місце, де контент несе власну розмітку
     (дозволений перелік тегів — у build.py, RICH_ALLOWED). Оформлення живе
     тут: у самому тексті немає ні class, ні style, тож правка контенту не
     дістає до вигляду сторінки. Селектори за тегом, бо класи ставити нікому. */
  /* Довжину рядка тримає ТЕКСТ, а не сам блок. Доти обмеження стояло на
     `.prose`, і разом із абзацами воно душило таблиці: реєстр аспірантів на 10
     колонок стискався до 680px, рядки розганялися до 1029px, а бібліографію
     доводилося читати горизонтальною прокруткою. Тепер 680px дістає кожен
     текстовий нащадок, а `.tablewrap` користується всією колонкою — і те саме
     виграють аналітичні матеріали, де таблиця опитування і є змістом. */
  .prose{max-width:none}
  .prose > :not(.tablewrap){max-width:680px}
  .prose p{color:var(--ink-2);font-size:14.5px;line-height:1.7;margin-top:10px}
  .prose a{color:var(--accent);text-decoration:underline;text-underline-offset:2px}
  .prose a:hover{color:var(--ink)}
  .prose strong{font-weight:600;color:var(--ink)}
  .prose em{font-style:italic}
  .prose h2,.prose h3,.prose h4{font-family:var(--font-display);color:var(--ink);line-height:1.3;margin-top:22px}
  .prose h2{font-size:19px;font-weight:600}
  .prose h3{font-size:16px;font-weight:600}
  .prose h4{font-size:14.5px;font-weight:500}
  .prose ul,.prose ol{margin-top:10px;padding-left:22px;color:var(--ink-2);font-size:14.5px;line-height:1.7}
  .prose li{margin-top:4px}
  .prose blockquote{margin-top:12px;padding-left:14px;border-left:2px solid var(--line-2);color:var(--ink-3)}
  .prose img{max-width:100%;height:auto;border-radius:10px;margin-top:14px;display:block}

  /* Таблиця в тексті — виняток, заведений заради аналітичних матеріалів: там
     результати опитувань і є змістом, а не оформленням (DESIGN.md §8). Обгортку
     .tablewrap ставить санітайзер, а не автор тексту: широка таблиця має
     прокручуватися всередині себе, інакше вона розсунула б сторінку вбік і
     зламала б колонку. Ширину колонок задає браузер — у контенті немає ні
     width, ні style, тож таблиця не може перебрати вибудову на себе. */
  .prose .tablewrap{overflow-x:auto;margin-top:16px;border:1px solid var(--line);border-radius:12px}
  .prose table{border-collapse:collapse;width:100%;font-size:13px;line-height:1.5;color:var(--ink-2)}
  .prose caption{caption-side:top;text-align:left;font-family:var(--font-mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-4);padding:12px 14px 2px}
  .prose th,.prose td{padding:9px 14px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}
  .prose th{font-weight:600;color:var(--ink);background:var(--surface);white-space:nowrap}
  .prose td{font-variant-numeric:tabular-nums}
  .prose tr:last-child td{border-bottom:0}
  .note{font-family:var(--font-mono);font-size:11px;color:var(--ink-4);margin-top:12px;line-height:1.5}

  .stats{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:24px}
  .stat{border:1px solid var(--line);border-radius:13px;padding:15px 16px}
  .stat b{font-family:var(--font-display);font-weight:600;font-size:26px;color:var(--ink);display:block;letter-spacing:-.02em}
  .stat span{font-size:12px;color:var(--ink-3);display:block;margin-top:2px;line-height:1.35}

  .tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px}
  .tile{border:1px solid var(--line);border-radius:13px;padding:16px;display:block;transition:border-color .15s,transform .15s,box-shadow .15s}
  .tile:hover{border-color:var(--line-2);transform:translateY(-2px);box-shadow:0 8px 22px -14px rgba(20,22,28,.28)}
  .tile__ic{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;font-size:18px;margin-bottom:10px}
  .tile h3{font-family:var(--font-display);font-weight:600;font-size:15px;color:var(--ink)}
  .tile p{font-size:12.5px;color:var(--ink-3);line-height:1.5;margin-top:3px}
  .tile__go{font-family:var(--font-mono);font-size:11px;color:var(--accent);margin-top:11px;display:flex;align-items:center;gap:5px;opacity:0;transform:translateX(-4px);transition:opacity .15s,transform .15s}
  .tile:hover .tile__go{opacity:1;transform:none}

  /* news list */
  .feed{margin-top:6px}
  .fitem{display:flex;gap:14px;padding:14px 0;border-bottom:1px solid var(--line);align-items:flex-start;transition:background .12s}
  .fitem:hover{background:var(--surface);border-radius:10px;padding-left:12px;padding-right:12px;margin-left:-12px;margin-right:-12px}
  /* Слот сталої ширини: у рядку може бути мініатюра або кольорова іконка
     категорії, і заголовки мають починатися з однієї вертикалі в обох випадках. */
  .fitem__media{width:72px;flex:none;display:flex;justify-content:center}
  .fitem__ic{width:38px;height:38px;border-radius:10px;flex:none;display:grid;place-items:center;font-size:18px}
  .fitem__thumb{width:72px;height:54px;border-radius:8px;object-fit:cover;display:block;background:var(--surface-2)}
  .fitem__b{flex:1;min-width:0}
  .fitem__t{font-size:14px;font-weight:500;color:var(--ink);line-height:1.4}
  /* Анонс під заголовком в архіві. Обрізається двома рядками: анонси
     різної довжини, і без обмеження рядки списку розʼїжджаються. */
  .fitem__s{font-size:13px;color:var(--ink-3);line-height:1.5;margin-top:4px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .fitem__m{font-family:var(--font-mono);font-size:11px;color:var(--ink-4);margin-top:4px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
  .dot{width:3px;height:3px;border-radius:50%;background:var(--ink-4)}
  .tagpill{font-family:var(--font-mono);font-size:10px;padding:2px 8px;border-radius:20px;letter-spacing:.02em}
  .morebtn{display:inline-flex;align-items:center;gap:7px;font-family:var(--font-body);font-weight:500;font-size:13px;padding:9px 16px;border-radius:9px;margin-top:16px;border:1px solid var(--line-2);color:var(--accent)}
  .morebtn:hover{background:var(--accent-soft);border-color:transparent}

  /* «Більше…» — довгий перелік згортається засобами самого браузера (<details>),
     без жодного JS. Прибираємо типовий трикутник, бо роль стрілки виконує
     шеврон, який повертається так само, як у групі меню. */
  summary.morebtn{cursor:pointer;list-style:none}
  summary.morebtn::-webkit-details-marker{display:none}
  summary.morebtn::marker{content:""}
  summary.morebtn svg.i{transition:transform .2s;color:var(--ink-4)}
  .more[open] > summary.morebtn svg.i{transform:rotate(90deg);color:var(--accent)}
  .more__hide{display:none}
  .more[open] > summary.morebtn .more__show{display:none}
  .more[open] > summary.morebtn .more__hide{display:inline}

  /* projects grid */
  .projgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:14px}
  .proj{border:1px solid var(--line);border-radius:12px;padding:15px;display:block;transition:border-color .15s,transform .15s,box-shadow .15s}
  a.proj:hover{border-color:var(--line-2);transform:translateY(-2px);box-shadow:0 8px 22px -15px rgba(20,22,28,.25)}
  .proj__t{font-size:13.5px;font-weight:500;color:var(--ink);line-height:1.42}
  .proj__d{font-family:var(--font-mono);font-size:11px;color:var(--accent);margin-top:9px;display:flex;align-items:center;gap:6px}
  .proj__d svg.i{font-size:13px}

  .grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:14px}
  .grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px}
  .card{border:1px solid var(--line);border-radius:13px;padding:16px;transition:border-color .15s,transform .15s,box-shadow .15s;display:block}
  .card:hover{border-color:var(--line-2);transform:translateY(-2px);box-shadow:0 8px 22px -15px rgba(20,22,28,.25)}
  .card h3{font-family:var(--font-display);font-weight:600;font-size:15px;color:var(--ink);line-height:1.3}
  .card p{font-size:12.5px;color:var(--ink-3);line-height:1.55;margin-top:5px}
  .card__k{font-family:var(--font-mono);font-size:10px;letter-spacing:.05em;color:var(--ink-4);text-transform:uppercase;margin-bottom:9px;display:block}

  .panel{border:1px solid var(--line);border-radius:15px;padding:20px;margin-top:14px;background:linear-gradient(180deg,#fbfbfe,#f6f6fb);position:relative;overflow:hidden}
  .panel::after{content:"";position:absolute;right:-40px;top:-40px;width:160px;height:160px;background:radial-gradient(circle,rgba(63,77,176,.12),transparent 70%)}
  .panel .eyebrow,.panel h3,.panel p,.panel .chips,.panel .pub{position:relative}
  .panel h3{font-family:var(--font-display);font-weight:600;font-size:18px;color:var(--ink);margin-top:6px;line-height:1.25;max-width:600px}
  .panel p{color:var(--ink-2);font-size:13.5px;line-height:1.6;margin-top:8px;max-width:600px}
  /* Керівник НДР — посилання на його сторінку. Глобально `a{color:inherit}`,
     тож без цього правила прізвище нічим не відрізнялося б від тексту поруч. */
  .panel p a{color:var(--accent)}
  .panel p a:hover{color:var(--ink)}
  .panel p strong{color:var(--ink);font-weight:600}
  /* Те саме для назви в заголовку панелі: у видань із власною сторінкою вона
     є посиланням, і сторінка «Видання» прямо це обіцяє читачеві. */
  .panel h3 a{color:var(--accent)}
  .panel h3 a:hover{color:var(--ink)}
  /* Книжка, що вийшла за результатами НДР, — той самий рядок `.pub`, лише
     всередині панелі. Три поправки на оточення. Перша: рядок стає
     `position:relative` разом із рештою вмісту (правило вище), інакше
     декоративне коло `.panel::after` лягає поверх нього. Друга: межа
     переїжджає з низу рядка нагору наступного, тобто малюється **між**
     рядками, а не після кожного. Глобального `.pub:last-child` тут замало —
     за переліком у панелі йдуть ще чіпи ключових слів, тож останній рядок
     `:last-child` не є й лишався б із висячою лінією над ними.
     Третя: рядок бере ту саму довжину, що `.panel h3` і `.panel p` — власного
     обмеження `.pub` не має й розтягнувся б на всі 1188px колонки, тоді як
     абзаци над ним тримаються 600px, і панель виглядала б удвічі вужчою за
     свій же останній рядок. Це та сама поправка, що `.formal` на сторінці
     захисту (DESIGN.md §8); нового числа не заводимо. */
  .panel .pub{border-bottom:none;max-width:600px}
  .panel .pub + .pub{border-top:1px solid var(--line)}

  .btn{display:inline-flex;align-items:center;gap:7px;font-family:var(--font-body);font-weight:500;font-size:13px;padding:9px 16px;border-radius:9px;margin-top:14px;background:var(--accent);color:#fff;transition:background .14s;position:relative}
  .btn:hover{background:#354299}
  .btn svg.i{font-size:15px}
  .btn--ghost{background:none;color:var(--accent);border:1px solid var(--line-2)}
  .btn--ghost:hover{background:var(--accent-soft);border-color:transparent}
  .btnrow{display:flex;gap:8px;flex-wrap:wrap}

  .chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
  .chip{font-size:12.5px;color:var(--ink-2);border:1px solid var(--line-2);border-radius:8px;padding:7px 13px;display:inline-flex;align-items:center;gap:7px;transition:all .14s}
  .chip:hover{border-color:var(--accent);color:var(--accent)}
  .chip svg.i{font-size:14px;color:var(--ink-4)}
  .chip:hover svg.i{color:var(--accent)}
  /* Чип із посиланням (напр. «Розділ книжки → …»): підсвічуємо саме назву,
     інакше її не відрізнити від підпису поруч. Решта чипів — не посилання. */
  .chip a{color:var(--accent)}
  .chip:hover a{color:var(--ink)}

  .tabs{display:flex;gap:6px;flex-wrap:wrap;margin:18px 0 4px;border-bottom:1px solid var(--line)}
  /* inline-block — щоб ряд однаково тримався і на <button> (фільтр), і на <a>
     (роки в архіві новин: там кожен рік — окрема сторінка, а не фільтр). */
  .tab{display:inline-block;font-size:13px;color:var(--ink-3);padding:8px 12px;border-radius:8px 8px 0 0;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .14s,border-color .14s}
  .tab:hover{color:var(--ink)}
  .tab.is-active{color:var(--accent);border-bottom-color:var(--accent)}

  /* Гортач сторінок — .pager (DESIGN.md §8).
     Кнопки, а не посилання: гортач нікуди не веде, він показує іншу частину
     того самого переліку на тій самій адресі — те саме, що робить ряд .tabs.
     Правило «фільтр — кнопка, перехід — посилання» діє й тут.
     Розмітку ставить app.js, тож у шаблонах цих класів немає. */
  /* scroll-margin-top — щоб перехід на іншу сторінку не заганяв верх переліку
     під напівпрозорий .topbar (він sticky, а прокручується .scroll). */
  .pager{display:flex;gap:6px;flex-wrap:wrap;align-items:center;scroll-margin-top:76px}
  /* Без цього рядка гортач НЕ ХОВАЄТЬСЯ. `app.js` ставить атрибут `hidden`,
     але типове правило браузера `[hidden]{display:none}` живе в таблиці
     користувацького агента й програє звичайному класу — `.pager{display:flex}`
     його перекриває. Наслідок був мовчазний і виглядав як поломка самого
     гортача: обравши коротку категорію, читач бачив ряд сторінок від
     попередньої вибірки, який нічого не робить (кнопки не перемальовувалися,
     бо `drawPager()` при схованому гортачі не викликається). Правило мусить
     мати специфічність не нижчу за `.pager`, тож клас + атрибут. */
  .pager[hidden]{display:none}
  .pager--top{margin:14px 0 2px}
  .pager--bottom{margin:18px 0 2px}
  .pager button{font-family:var(--font-body);font-size:13px;line-height:1;padding:8px 11px;border-radius:9px;border:1px solid var(--line-2);color:var(--ink-3);transition:color .14s,border-color .14s,background .14s}
  .pager button:hover:not(:disabled){color:var(--ink);background:var(--accent-soft);border-color:transparent}
  .pager__n{min-width:36px;font-variant-numeric:tabular-nums}
  .pager__n.is-active{color:#fff;background:var(--accent);border-color:transparent}
  .pager__n.is-active:hover{color:#fff;background:#354299}
  /* Недоступний край переліку лишається на місці, а не зникає: інакше ряд
     сіпався б завширшки на першій і останній сторінці. */
  .pager button:disabled{opacity:.4;cursor:default}
  .pager__gap{font-family:var(--font-mono);font-size:12px;color:var(--ink-4);padding:0 2px;user-select:none}

  /* people */
  .dept-head{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap;margin-top:6px}
  .person{display:flex;gap:11px;align-items:center;border:1px solid var(--line);border-radius:11px;padding:11px;transition:border-color .14s}
  .person:hover{border-color:var(--accent)}
  .pav{width:38px;height:38px;border-radius:50%;flex:none;display:grid;place-items:center;font-family:var(--font-display);font-weight:600;font-size:13px}
  .person b{font-size:13px;font-weight:500;color:var(--ink);display:block;line-height:1.25}
  .person span{font-size:11.5px;color:var(--ink-4)}
  .prof{width:84px;height:84px;border-radius:20px;display:grid;place-items:center;flex:none;font-family:var(--font-display);font-weight:600;font-size:28px}
  /* Фото на місці аватарки з ініціалів: та сама коробка, тож сітка карток і
     шапка профілю не залежать від того, чи є в людини світлина. */
  .pav-photo,.prof-photo{object-fit:cover;background:var(--surface-2);border:1px solid var(--line)}
  .side2{display:grid;grid-template-columns:1fr 220px;gap:24px;margin-top:16px}
  .metabox{border:1px solid var(--line);border-radius:13px;padding:15px;background:var(--surface);height:max-content}
  .metabox .r+.r{border-top:1px solid var(--line-2);margin-top:11px;padding-top:11px}
  .metabox .k{font-family:var(--font-mono);font-size:10px;letter-spacing:.06em;color:var(--ink-4);text-transform:uppercase}
  .metabox .v{font-size:13px;color:var(--ink-2);margin-top:3px}
  /* Значення-посилання: підрозділ співробітника, ORCID і Scholar, пошта й
     телефон редакції, сайт журналу. Доти акцентний колір з'являвся лише на
     наведення, тож посилання було не відрізнити від сусіднього рядка даних —
     а на дотику наведення немає взагалі. Тепер як у решті сайту: акцент у
     спокої, темний на наведення (`.pub a`, `.panel p a`, `p.para a`). */
  .metabox .v a{color:var(--accent)}
  .metabox .v a:hover{color:var(--ink)}

  /* Формальні відомості про захист: речення про раду, регалії осіб, підписи
     документів. Усе це — суцільний текст, який читають підряд, тож рядок у
     них має бути ОДИН. Без цього абзац тримався 680px (як уся проза), а рядок
     особи тягнувся на всі 1188px колонки, і блок виглядав удвічі вужчим за
     те, що йшло під ним. Ширина взята та сама, що в прози, — нового числа
     тут не заводимо. */
  .formal{max-width:680px}
  .pub{display:flex;gap:11px;padding:11px 0;border-bottom:1px solid var(--line);align-items:flex-start}
  .pub:last-child{border-bottom:none}
  .pub svg.i{font-size:17px;color:var(--accent);margin-top:1px;flex:none}
  .pub div{font-size:13px;color:var(--ink-2);line-height:1.5}
  .pub em{font-style:normal;color:var(--ink);font-weight:500}
  /* Назва-посилання: видання з власною сторінкою, розділ у змісті, автор.
     Глобально `a` успадковує колір, тож без цього рядка посилання в переліку
     не відрізнити від звичайного тексту й ніхто його не натисне. Сигнал той
     самий, що в решті сайту, — акцентний колір (`.crumb`, `.prose`, метабокс). */
  .pub a{color:var(--accent)}
  .pub a em{color:inherit}
  .pub a:hover,.pub a:hover em{color:var(--ink)}

  /* defense list */
  .def{border:1px solid var(--line);border-radius:12px;padding:15px;margin-top:10px;display:block;transition:border-color .15s,box-shadow .15s}
  .def:hover{border-color:var(--line-2);box-shadow:0 8px 22px -16px rgba(20,22,28,.25)}
  .def__top{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;align-items:baseline}
  .def__n{font-size:14px;font-weight:500;color:var(--ink)}
  .def__date{font-family:var(--font-mono);font-size:11.5px;color:var(--accent)}
  .def__t{font-size:12.5px;color:var(--ink-2);line-height:1.5;margin-top:5px}
  .def__m{font-family:var(--font-mono);font-size:11px;color:var(--ink-4);margin-top:7px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
  .badge{font-family:var(--font-mono);font-size:10px;padding:2px 8px;border-radius:20px}
  .badge--up{background:var(--teal-soft);color:var(--teal)}
  .badge--done{background:var(--surface-2);color:var(--ink-3)}

  .foot{border-top:1px solid var(--line);margin-top:46px;padding-top:24px;display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:22px}
  .foot h4{font-family:var(--font-display);font-weight:600;font-size:14px;color:var(--ink)}
  .foot p,.foot a{font-size:13px;color:var(--ink-3);line-height:1.8;display:block}
  .foot a:hover{color:var(--accent)}
  .copy{font-family:var(--font-mono);font-size:11px;color:var(--ink-4);margin-top:26px;padding-top:16px;border-top:1px solid var(--line)}
  .scrim{display:none}

  @media(max-width:860px){
    .app{grid-template-columns:1fr}
    .rail{position:fixed;left:0;top:0;width:280px;transform:translateX(-100%);transition:transform .26s cubic-bezier(.4,0,.2,1)}
    .rail.is-open{transform:none;box-shadow:0 0 60px rgba(0,0,0,.4)}
    .burger{display:block}
    .scrim{position:fixed;inset:0;background:rgba(10,12,16,.5);z-index:35;opacity:0;pointer-events:none;transition:opacity .26s}
    .scrim.is-open{display:block;opacity:1;pointer-events:auto}
    .stats{grid-template-columns:1fr 1fr}
    .tiles,.grid3,.projgrid{grid-template-columns:1fr}
    .grid2,.side2{grid-template-columns:1fr}
    .foot{grid-template-columns:1fr}
    .search kbd{display:none}
    h1.h{font-size:26px}
    .wrap{padding:24px 18px 60px}
    .topbar{padding:10px 16px}
  }
  @media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
  :focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}

  .navgroup{margin-bottom:1px}
  .nav .chev{margin-left:auto;font-size:15px;color:var(--rail-dim);transition:transform .2s;padding:3px;border-radius:5px;cursor:pointer}
  .nav .chev:hover{color:#fff;background:#33407a}
  .navgroup.is-open .nav .chev{transform:rotate(90deg);color:var(--accent-2)}
  .subnav{overflow:hidden;max-height:0;transition:max-height .26s ease;margin:1px 0 4px 4px;border-left:1px solid var(--rail-line);padding-left:4px}
  .navgroup.is-open .subnav{max-height:360px}
  .subnav a{display:block;padding:6px 10px 6px 34px;font-size:12.5px;color:var(--rail-dim);border-radius:8px;cursor:pointer;transition:background .14s,color .14s}
  .subnav a:hover{color:#eef0f3;background:#2b3566}
  .subnav a.is-active{color:#fff;background:#2b3566}
  .view h2.s{scroll-margin-top:78px}

  /* Банер угорі головної (DESIGN.md §8). Пропорція задана тут, а не атрибутами
     width/height у розмітці: разом із width:100% вона резервує висоту ще до
     завантаження картинки, тож сторінка не стрибає, коли банер приїде. Він же
     LCP-елемент — стрибок був би найпомітнішим саме тут. object-fit:cover
     означає, що інша за пропорцією заміна обріжеться, а не зламає розкладку. */
  /* max-height: у широкій колонці (1188px = 1240 мінус поля) пропорція дала б
     546px — банер з’їдав би весь перший екран і зсував новини за згин.
     Обмеження підрізає верх і низ кадру, тобто небо й дорогу. У вужчій колонці
     висота й так менша за межу, тож правило там нічого не змінює й окремого
     breakpoint не потребує.

     **Межу задає не смак, а поля самого банера, і міряти їх треба щоразу, коли
     банер міняють.** Знак і назва в поточному малюнку лежать між 8.2% і 91.8%
     висоти, тобто вільного поля згори й знизу — близько 8%. При 440px у кадрі
     лишалося б 9.7%–90.3%, і 8 жовтня 2026 це різало **півслова «України»**
     внизу й верх знака згори. 470px лишають 7.0%–93.0%, тобто обрізається саме
     поле, а не зміст, із запасом ~1.2% з кожного боку.

     Попередній малюнок мав поля ~20% і 17%, через що 440px йому вистачало. Тож
     нове тло з іншими полями вимагає нового числа: порахувати можна так —
     max-height = (1 − 2 × «вільне поле у відсотках» + запас) × 546. */
  .hero{display:block;width:100%;height:auto;aspect-ratio:2480/1140;max-height:470px;object-fit:cover;
    border:1px solid var(--line);border-radius:13px;background:var(--surface);margin-bottom:20px}
  /* На вузькому екрані широка смуга стискає знак і назву в нечитабельну дрібноту:
     беремо вищий кадр і тримаємо його по лівому краю, де вони й лежать. */
  @media(max-width:860px){.hero{aspect-ratio:16/9;object-position:left center}}

  /* Ряд монографій на головній (DESIGN.md §8) */
  .monorow{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-top:14px}
  .mono-card{display:block;transition:transform .15s}
  .mono-card:hover{transform:translateY(-3px)}
  .mono-cover{aspect-ratio:3/4;border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--surface)}
  .mono-cover img{width:100%;height:100%;object-fit:cover;display:block}
  .mono-t{font-family:var(--font-display);font-weight:500;font-size:12.5px;color:var(--ink);line-height:1.3;margin-top:8px;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .mono-y{font-family:var(--font-mono);font-size:11px;color:var(--ink-4);margin-top:3px}
  @media(max-width:860px){.monorow{grid-template-columns:repeat(2,1fr)}}
