MediaWiki:Common.js: відмінності між версіями

Матеріал з Київський національний лінгвістичний університет
Перейти до навігації Перейти до пошуку
Немає опису редагування
Немає опису редагування
Мітка: Скасовано
Рядок 1: Рядок 1:
$(function() {
/* ── Заголовок сторінки ── */
     $('.category-card').each(function() {
#firstHeading {
        var $card = $(this);
    font-size: clamp(28px, 4vw, 48px);
        var href = $card.attr('data-href');
}
       
 
        if (href) {
/* ── Бокове меню ── */
            $card.css('cursor', 'pointer');
#mw-panel {
           
     font-size: clamp(14px, 1.2vw, 18px);
            $card.on('click', function(e) {
}
                if ($(e.target).closest('a').length === 0) {
 
                    window.location.href = href;
/* ── Прибираємо обмеження Vector ── */
                }
body.skin-vector-2022 .mw-page-container-inner,
            });
body.skin-vector .mw-content-container,
           
body.skin-vector .vector-body,
            $card.hover(
body.skin-vector #bodyContent {
                function() { $card.addClass('card-hover'); },
    max-width: none !important;
                function() { $card.removeClass('card-hover'); }
    padding-left: 0 !important;
            );
    padding-right: 0 !important;
        }
}
     });
 
});
body.skin-vector-2022 .mw-body,
/* ── Випадкові статті на головній сторінці ── */
body.skin-vector-2022 .mw-body-content {
    max-width: none !important;
    margin: 0 !important;
}
 
/* ════════════════════════════════════
  ПРИВІТАННЯ + СТАТИСТИКА
═══════════════════════════════════════ */
.welcome-wrapper {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
    padding: 40px 5vw 40px;
    box-sizing: border-box;
    width: 100%;
}
 
.welcome-text {
    flex: 1;
    text-align: center;
    /* Зміщуємо центр тексту компенсуючи ширину панелі статистики */
    transform: translateX(-80px);
}
 
.welcome-subtitle {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 1.45rem;
    font-weight: 400;
    color: #444;
    letter-spacing: 0.6px;
    margin-bottom: 10px;
    opacity: 0.92;
}
 
.welcome-title {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 2.45rem;
    font-weight: 700;
    line-height: 1.18;
    color: #003d82;
     letter-spacing: -0.3px;
    margin: 0;
}


/* Витягнути назву зображення з вікі-тексту */
/* ── Панель статистики (справа від привітання) ── */
function extractImageName(wikitext) {
.stats-panel {
     if (!wikitext) return null;
    width: 260px;
    flex-shrink: 0;
    background: white;
    border-radius: 16px;
    border: 1px solid rgba(0,61,130,0.08);
     box-shadow: 0 6px 24px rgba(0,0,0,0.07);
    overflow: hidden;
}


     // 1. Шукаємо в Infobox: | image = Файл.jpg
.stats-panel-header {
     var infoboxImg = wikitext.match(/\|\s*image\s*=\s*([^\|\n\}]+)/i);
     background: rgba(210, 230, 255, 0.35);
     if (infoboxImg) {
    color: #003d82;
        var name = infoboxImg[1].trim();
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
        if (name && name.length > 0) return name;
    font-size: 1rem;
     }
    font-weight: 700;
     padding: 12px 18px;
     border-bottom: 1px solid rgba(0,61,130,0.1);
}
 
.stats-panel-list {
    padding: 4px 0;
}
 
.stats-panel-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 18px;
    border-bottom: 1px solid rgba(0,61,130,0.05);
    transition: background 0.2s;
}
 
.stats-panel-item:last-child {
     border-bottom: none;
}


    // 2. Шукаємо [[Файл:Назва.jpg|...]] або [[File:...]]
.stats-panel-item:hover {
     var fileMatch = wikitext.match(/\[\[(?:Файл|File|Зображення|Image):([^\|\]]+)/i);
     background: rgba(210, 230, 255, 0.2);
    if (fileMatch) {
}
        return fileMatch[1].trim();
    }


     return null;
.stats-panel-label {
     font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 14px;
    color: #555;
}
}


/* Витягнути перший змістовний абзац */
.stats-panel-number {
function extractDescription(wikitext) {
     font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
     if (!wikitext) return '';
    font-size: 18px;
    font-weight: 800;
    color: #003d82;
}


    // Прибрати інфобокс {{...}} (може бути багаторядковим)
/* ════════════════════════════════════
     var text = wikitext;
  ЗАГОЛОВОК КАТЕГОРІЙ
     var depth = 0;
═══════════════════════════════════════ */
     var infoboxEnd = -1;
.section-categories {
     for (var i = 0; i < text.length; i++) {
     font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
        if (text[i] === '{') depth++;
     font-size: 2.1rem;
        else if (text[i] === '}') {
     font-weight: 700;
            depth--;
     color: #003d82;
            if (depth === 0) { infoboxEnd = i + 1; break; }
    text-align: center;
        }
    margin: 30px 0 30px;
     }
     /* Компенсуємо ширину правої колонки щоб текст був по центру сітки */
     if (infoboxEnd > 0) text = text.substring(infoboxEnd);
     padding: 0 calc(360px + 24px) 0 0;
    background: transparent;
    box-sizing: border-box;
}


     // Прибрати [[Файл:...]] блоки
.section-categories::after {
     text = text.replace(/\[\[(?:Файл|File|Зображення|Image):[^\]]*\]\]/gi, '');
     content: '';
    display: block;
    width: 90px;
    height: 4px;
    background: #ffd700;
     margin: 14px auto 0;
    border-radius: 2px;
}


    // Прибрати wikitable {| ... |}
/* ════════════════════════════════════
     text = text.replace(/\{\|[\s\S]*?\|\}/g, '');
  ОСНОВНИЙ LAYOUT: категорії + права колонка
═══════════════════════════════════════ */
.main-content-layout {
     display: flex;
    gap: 24px;
    align-items: flex-start;
    padding: 0 5vw;
    margin: 0 0 70px;
    box-sizing: border-box;
    width: 100%;
}


    // Прибрати шаблони {{...}}
/* ── Сітка карток — 3 в ряд ── */
     text = text.replace(/\{\{[^}]*\}\}/g, '');
.category-grid-container {
     display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    flex: 1;
    min-width: 0;
}


    // Прибрати заголовки == ... ==
/* ── Права колонка ── */
     text = text.replace(/={2,6}[^=\n]+=+/g, '');
.right-column {
    width: 360px;
    min-width: 360px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
    align-self: flex-start;
     padding-top: 0;
}


    // Прибрати вікі-посилання — залишити текст
/* ════════════════════════════════════
     text = text.replace(/\[\[(?:[^\|\]]*\|)?([^\]]+)\]\]/g, '$1');
  КАРТКИ КАТЕГОРІЙ
═══════════════════════════════════════ */
.category-card {
    background: white;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 6px 24px rgba(0,0,0,0.08);
     transition: all 0.28s cubic-bezier(0.165, 0.84, 0.44, 1);
    cursor: pointer;
    border: 1px solid rgba(0,61,130,0.08);
    height: 100%;
    display: flex;
    flex-direction: column;
}


     // Прибрати зовнішні посилання [url текст]
.category-card:hover {
     text = text.replace(/\[[^\s\]]+\s+([^\]]+)\]/g, '$1');
     transform: translateY(-6px);
     text = text.replace(/\[[^\]]+\]/g, '');
     box-shadow: 0 20px 40px rgba(0,61,130,0.18);
     border-color: rgba(0,61,130,0.15);
}


     // Прибрати жирний/курсив
.card-image {
     text = text.replace(/'{2,3}/g, '');
     padding: 28px 0 16px;
     flex-grow: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;
}


     // Прибрати HTML теги
.card-image img {
     text = text.replace(/<[^>]+>/g, '');
    width: 88px;
     height: 88px;
     object-fit: contain;
    transition: transform 0.35s ease;
}


    // Прибрати рядки що починаються з * # : ;
.category-card:hover .card-image img {
     text = text.replace(/^[\*#:;].*/gm, '');
     transform: scale(1.12);
}


     // Прибрати порожні рядки і зайві пробіли
.card-title {
     var lines = text.split('\n').map(function(l) { return l.trim(); }).filter(function(l) { return l.length > 20; });
    font-size: 15px;
    font-weight: 600;
     color: #003d82;
     text-align: center;
    padding: 8px 12px 12px;
    line-height: 1.4;
    flex-grow: 0;
    background: rgba(210, 230, 255, 0.15);
    border-radius: 10px;
    margin: 0 10px 14px;
}


     // Взяти перший змістовний рядок
.card-title pre {
     if (lines.length > 0) {
    background: transparent !important;
        var result = lines[0].substring(0, 160);
    border: none !important;
        if (lines[0].length > 160) result += '…';
     box-shadow: none !important;
        return result;
     padding: 0 !important;
     }
    margin: 0 !important;
    font-family: inherit !important;
    font-size: inherit !important;
    font-weight: inherit !important;
    color: inherit !important;
     white-space: normal !important;
}


     return '';
/* ════════════════════════════════════
  ВИПАДКОВІ СТАТТІ
═══════════════════════════════════════ */
.random-articles-panel {
     background: white;
    border-radius: 16px;
    border: 1px solid rgba(0,61,130,0.08);
    box-shadow: 0 6px 24px rgba(0,0,0,0.07);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
}
}


function loadRandomArticles() {
    var list = document.getElementById('random-articles-list');
    if (!list) return;


    list.innerHTML = '<div class="random-articles-loading">Завантаження...</div>';


     var apiBase = mw.config.get('wgScriptPath') + '/api.php';
.random-articles-header {
     background: rgba(210, 230, 255, 0.35);
    color: #003d82;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 1rem;
    font-weight: 700;
    padding: 14px 18px;
    border-bottom: 1px solid rgba(0,61,130,0.1);
}


     // Сторінки які не повинні з'являтись у випадкових статтях
#random-articles-list {
     var excludedPages = ['Головна сторінка', 'Структурні підрозділи', 'Викладачі'];
     padding: 12px;
     display: flex;
    flex-direction: column;
    gap: 12px;
}


     fetch(apiBase + '?action=query&list=random&rnnamespace=0&rnlimit=10&format=json')
.random-article-card {
        .then(function(r) { return r.json(); })
    display: flex;
        .then(function(data) {
    gap: 14px;
            var pages = data.query.random.filter(function(p) {
    padding: 14px;
                return excludedPages.indexOf(p.title) === -1;
    border-radius: 12px;
            }).slice(0, 3);
     background: rgba(210, 230, 255, 0.12);
    border: 1px solid rgba(0,61,130,0.07);
    text-decoration: none;
    color: inherit;
    transition: all 0.22s ease;
    align-items: flex-start;
}


            var titles = pages.map(function(p) { return p.title; }).join('|');
.random-article-card:hover {
    background: rgba(210, 230, 255, 0.35);
    border-color: rgba(0,61,130,0.18);
    transform: translateX(3px);
    text-decoration: none;
}


            return fetch(
.random-article-thumb {
                apiBase +
    width: 90px;
                '?action=query' +
    height: 90px;
                '&titles=' + encodeURIComponent(titles) +
    border-radius: 10px;
                '&prop=revisions' +
    object-fit: cover;
                '&rvprop=content' +
    flex-shrink: 0;
                '&format=json'
    background: #eef2f8;
            );
}
        })
        .then(function(r) { return r.json(); })
        .then(function(data) {
            var pages = Object.values(data.query.pages);
            list.innerHTML = '';


            var promises = pages.map(function(page) {
.random-article-thumb-placeholder {
                var title = page.title;
    width: 90px;
                var pageUrl = mw.config.get('wgArticlePath').replace(
    height: 90px;
                    '$1', encodeURIComponent(title.replace(/ /g, '_'))
    border-radius: 10px;
                );
    flex-shrink: 0;
    background: linear-gradient(135deg, #e8eef7, #c8d8ee);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
}


                var content = '';
.random-article-info {
                if (page.revisions && page.revisions[0]) {
    flex: 1;
                    content = page.revisions[0]['*'] || '';
    min-width: 0;
                }
}


                var excerpt = extractDescription(content);
.random-article-title {
                if (!excerpt) excerpt = 'Немає опису.';
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 15px;
    font-weight: 700;
    color: #003d82;
    margin-bottom: 6px;
    line-height: 1.35;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}


                var imgName = extractImageName(content);
.random-article-excerpt {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 13px;
    color: #555;
    line-height: 1.45;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}


                if (imgName) {
.random-articles-loading {
                    var fileTitle = imgName.match(/^(Файл|File|Image|Зображення):/i)
    padding: 20px;
                        ? imgName
    text-align: center;
                        : 'File:' + imgName;
    color: #888;
    font-size: 13px;
    font-family: system-ui, sans-serif;
}


                    return fetch(
.random-articles-refresh {
                        apiBase +
    display: none;
                        '?action=query' +
}
                        '&titles=' + encodeURIComponent(fileTitle) +
                        '&prop=imageinfo' +
                        '&iiprop=url' +
                        '&iiurlwidth=120' +
                        '&format=json'
                    )
                    .then(function(r) { return r.json(); })
                    .then(function(imgData) {
                        var imgPages = Object.values(imgData.query.pages);
                        var imgSrc = null;
                        if (imgPages[0] && imgPages[0].imageinfo && imgPages[0].imageinfo[0]) {
                            imgSrc = imgPages[0].imageinfo[0].thumburl || imgPages[0].imageinfo[0].url;
                        }
                        return { title: title, excerpt: excerpt, pageUrl: pageUrl, imgSrc: imgSrc };
                    })
                    .catch(function() {
                        return { title: title, excerpt: excerpt, pageUrl: pageUrl, imgSrc: null };
                    });
                }


                return Promise.resolve({ title: title, excerpt: excerpt, pageUrl: pageUrl, imgSrc: null });
/* ════════════════════════════════════
            });
  РЕСУРСИ ТА ПОСИЛАННЯ
═══════════════════════════════════════ */
.resources-and-contacts {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    margin: 30px 0 50px;
    align-items: stretch;
}


            return Promise.all(promises);
.resource-block,
        })
.contacts-block {
        .then(function(results) {
    flex: 1;
            var list2 = document.getElementById('random-articles-list');
    min-width: 300px;
            if (!list2) return;
    background: rgba(220, 235, 255, 0.18);
            list2.innerHTML = '';
    border: 1px solid rgba(180, 210, 240, 0.5);
    border-radius: 14px;
    padding: 28px 32px;
    box-shadow: 0 4px 12px rgba(0,61,130,0.06);
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
}


            results.forEach(function(item) {
.resource-block ul,
                var thumbHtml = item.imgSrc
.contacts-block ul {
                    ? '<img class="random-article-thumb" src="' + item.imgSrc + '" alt="">'
    flex: 1;
                    : '<div class="random-article-thumb-placeholder">📄</div>';
    list-style: none;
    padding-left: 0;
    margin: 0;
}


                var card = document.createElement('a');
.resource-block h2,
                card.href = item.pageUrl;
.contacts-block h2 {
                card.className = 'random-article-card';
    font-size: 1.3rem !important;
                card.innerHTML =
    font-weight: 700 !important;
                    thumbHtml +
    color: #003d82 !important;
                    '<div class="random-article-info">' +
    margin: 0 0 20px 0 !important;
                        '<div class="random-article-title">' + mw.html.escape(item.title) + '</div>' +
    padding: 0 0 14px 0 !important;
                        '<div class="random-article-excerpt">' + mw.html.escape(item.excerpt) + '</div>' +
    border: none !important;
                    '</div>';
    border-bottom: 2px solid rgba(0,61,130,0.12) !important;
    line-height: 1.3 !important;
}


                list2.appendChild(card);
.resource-block li,
            });
.contacts-block li {
        })
    margin-bottom: 11px;
        .catch(function(err) {
    line-height: 1.6;
            var list3 = document.getElementById('random-articles-list');
    font-size: 1rem;
            if (list3) list3.innerHTML = '<div class="random-articles-loading">Не вдалося завантажити статті.</div>';
    color: #444;
            console.error('[RA] error:', err);
    padding-left: 14px;
        });
    position: relative;
}
}


/* Запуск */
.resource-block li::before,
mw.hook('wikipage.content').add(function() {
.contacts-block li::before {
     var panel = document.getElementById('random-articles-panel');
    content: '';
     if (!panel) return;
    position: absolute;
    left: 0;
    color: #003d82;
     font-weight: 700;
     opacity: 0.5;
}


     loadRandomArticles();
.resource-block li a,
.contacts-block li a {
     color: #1e40af;
    text-decoration: none;
    transition: color 0.2s;
}


    var btn = document.getElementById('random-articles-refresh');
.resource-block li a:hover,
     if (btn) {
.contacts-block li a:hover {
         btn.addEventListener('click', function() {
    color: #003d82;
            loadRandomArticles();
     text-decoration: underline;
         });
}
 
/* ════════════════════════════════════
  АДАПТИВНІСТЬ
═══════════════════════════════════════ */
@media (max-width: 1100px) {
    .welcome-wrapper {
        flex-direction: column;
         text-align: center;
    }
    .stats-panel {
        width: 100%;
        max-width: 400px;
    }
    .main-content-layout {
        flex-direction: column;
    }
    .right-column {
        width: 100%;
        min-width: unset;
        flex-direction: row;
         flex-wrap: wrap;
    }
    .category-grid-container {
        grid-template-columns: repeat(3, 1fr);
     }
     }
});
}


/* ══════════════════════════════════════════════
@media (max-width: 820px) {
  ГОЛОВНА СТОРІНКА: покращення
    .category-grid-container {
══════════════════════════════════════════════ */
        grid-template-columns: repeat(2, 1fr);
    }
}


/* ── 1. AOS: анімації при скролі ── */
@media (max-width: 520px) {
mw.loader.getScript('https://unpkg.com/aos@2.3.1/dist/aos.js').then(function() {
     .category-grid-container {
     mw.loader.load('https://unpkg.com/aos@2.3.1/dist/aos.css', 'text/css');
         grid-template-columns: 1fr;
   
    if (typeof AOS !== 'undefined') {
         AOS.init({
            duration: 600,
            easing: 'ease-out-cubic',
            once: true,
            offset: 50
        });
     }
     }
});
    .welcome-title { font-size: 2rem; }
    .welcome-subtitle { font-size: 1.25rem; }
    .section-categories { font-size: 1.8rem; }
}


/* ── 2. Анімація чисел статистики ── */
@media (max-width: 900px) {
function animateNumber(element, target) {
     .resources-and-contacts {
     element.classList.add('animating');
         flex-direction: column;
    var current = 0;
         gap: 20px;
    var increment = target / 60; // 60 кадрів
     }
    var timer = setInterval(function() {
         current += increment;
        if (current >= target) {
            current = target;
            clearInterval(timer);
            setTimeout(function() { element.classList.remove('animating'); }, 100);
        }
         element.textContent = Math.floor(current);
     }, 16); // ~60 FPS
}
}


mw.hook('wikipage.content').add(function() {
/* ── Ліва колонка з заголовком і сіткою ── */
    // Запускаємо анімацію тільки на головній сторінці
.category-column {
    if (mw.config.get('wgPageName') !== 'Головна_сторінка') return;
     flex: 1;
   
     min-width: 0;
    var statsNumbers = document.querySelectorAll('.stats-panel-number');
     display: flex;
     var animated = false;
     flex-direction: column;
      
}
    function checkAndAnimate() {
        if (animated) return;
        var statsPanel = document.querySelector('.stats-panel');
        if (!statsPanel) return;
       
        var rect = statsPanel.getBoundingClientRect();
        if (rect.top < window.innerHeight && rect.bottom > 0) {
            animated = true;
            statsNumbers.forEach(function(el) {
                var text = el.textContent.trim();
                var num = parseInt(text.replace(/[^\d]/g, ''), 10);
                if (!isNaN(num) && num > 0) {
                    el.textContent = '0';
                    setTimeout(function() { animateNumber(el, num); }, 200);
                }
            });
        }
     }
   
    window.addEventListener('scroll', checkAndAnimate);
     checkAndAnimate();
});


.category-column .category-grid-container {
    flex: 1;
}




/* ── 4. Сортування карточок за прізвищем ── */
    .timeline-dot {
mw.hook('wikipage.content').add(function() {
        left: -33px;
     document.querySelectorAll('div[style*="grid-template-columns"]').forEach(function(grid) {
    }
         var cards = Array.from(grid.children);
     .timeline-year {
         if (cards.length < 2) return;
         font-size: 1.2rem;
    }
    .timeline-event {
         font-size: 14px;
    }
}


        cards.sort(function(a, b) {
            var aLink = a.querySelector('div[style*="flex-grow"] a');
            var bLink = b.querySelector('div[style*="flex-grow"] a');
            if (!aLink || !bLink) return 0;


            var aSurname = aLink.textContent.trim().split(' ')[0];
            var bSurname = bLink.textContent.trim().split(' ')[0];


            return aSurname.localeCompare(bSurname, 'uk');
        });


        cards.forEach(function(card) {
            grid.appendChild(card);
        });
    });
});


/* ══════════════════════════════════════════════
/* ══════════════════════════════════════════════
   ТАЙМЛАЙН ІСТОРІЇ УНІВЕРСИТЕТУ
   MODERN UI: градієнти, glassmorphism, анімації
══════════════════════════════════════════════ */
══════════════════════════════════════════════ */


var timelineData = [
/* ── Прогрес скролла ── */
     { year: 1948, event: "Заснування університету" },
.scroll-progress {
     { year: 1962, event: "Початок наукової школи прагмалінгвістики та мовленнєвої комунікації" },
    position: fixed;
     { year: 1963, event: "Започаткування школи комп'ютерної лінгвістики та статистичної лексикографії" },
    top: 0;
     { year: 1972, event: "Створення школи лінгвостилістики в синхронії та діахронії" },
     left: 0;
     { year: 1992, event: "Заснування наукової школи контрастивної семантики і типології" },
    height: 4px;
     { year: 1993, event: "Відкриття першої в Україні кафедри ЮНЕСКО" },
    background: linear-gradient(90deg, #003d82, #0066cc, #ffd700);
     { year: 1994, event: "Внесення до реєстру закладів освіти України з IV рівнем акредитації" },
    z-index: 99999;
     { year: 1996, event: "Формування школи зарубіжного і порівняльного літературознавства" },
    transition: width 0.1s ease;
     { year: 2000, event: "Проведення Міжнародної конференції ЮНЕСКО «Лінгвопакс-VIII»" }
    box-shadow: 0 2px 8px rgba(0, 61, 130, 0.3);
];
}
 
/* ── Градієнтний фон для welcome ── */
.welcome-wrapper {
    background: linear-gradient(180deg,
        rgba(210, 230, 255, 0.4) 0%,
        rgba(210, 230, 255, 0.25) 40%,
        rgba(255, 255, 255, 0) 100%);
    position: relative;
    overflow: hidden;
     padding-bottom: 60px !important;
}
 
/* Плавний перехід до білого фону */
.welcome-wrapper::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 80px;
    background: linear-gradient(to bottom, transparent, white);
    pointer-events: none;
    z-index: 1;
}
 
.welcome-text,
.stats-panel {
     position: relative;
    z-index: 2;
}
 
/* ── Glassmorphism для статистики ── */
.stats-panel {
    background: rgba(255, 255, 255, 0.7) !important;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.3) !important;
     box-shadow: 0 8px 32px rgba(0, 61, 130, 0.15) !important;
}
 
.stats-panel-header {
    background: linear-gradient(135deg, rgba(0, 61, 130, 0.1), rgba(0, 102, 204, 0.15)) !important;
}
 
/* ── Glassmorphism для випадкових статей ── */
.random-articles-panel {
    background: rgba(255, 255, 255, 0.75) !important;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
     border: 1px solid rgba(255, 255, 255, 0.3) !important;
}
 
/* ── Градієнтні картки категорій ── */
.category-card {
    background: linear-gradient(135deg, #ffffff 0%, #f8fbff 100%);
    border: 1px solid rgba(0, 61, 130, 0.08);
     position: relative;
    overflow: hidden;
}
 
.category-card::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: linear-gradient(135deg, transparent, rgba(0, 61, 130, 0.05), transparent);
    transform: rotate(45deg);
    transition: all 0.6s ease;
    opacity: 0;
}
 
.category-card:hover::before {
    opacity: 1;
     top: -25%;
    left: -25%;
}
 
/* ── Мікроанімації: bounce для іконок ── */
.category-card:hover .card-image img {
     animation: icon-bounce 0.6s ease;
}
 
@keyframes icon-bounce {
    0%, 100% { transform: scale(1.12) translateY(0); }
     50% { transform: scale(1.12) translateY(-8px); }
}
 
/* ── Gradient hover для карточок ── */
.category-card {
    transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
}


mw.hook('wikipage.content').add(function() {
.category-card:hover {
     var container = document.getElementById('history-timeline');
     transform: translateY(-8px) scale(1.02);
    if (!container) return;
     box-shadow: 0 24px 48px rgba(0, 61, 130, 0.2);
      
}
    timelineData.forEach(function(item, index) {
        var point = document.createElement('div');
        point.className = 'timeline-point';
        point.setAttribute('data-aos', 'fade-up');
        point.setAttribute('data-aos-delay', (100 + index * 100).toString());
       
        point.innerHTML =
            '<div class="timeline-dot"></div>' +
            '<div class="timeline-content">' +
                '<div class="timeline-year">' + item.year + '</div>' +
                '<div class="timeline-event">' + item.event + '</div>' +
            '</div>';
       
        container.appendChild(point);
    });
});


/* ── AOS на картки категорій ── */
/* ── Pulse для чисел статистики ── */
mw.hook('wikipage.content').add(function() {
.stats-panel-number {
     if (mw.config.get('wgPageName') !== 'Головна_сторінка') return;
     animation: number-pulse 2s ease-in-out infinite;
   
}
    var cards = document.querySelectorAll('.category-card');
    cards.forEach(function(card, index) {
        card.setAttribute('data-aos', 'fade-up');
        card.setAttribute('data-aos-delay', (100 + (index % 12) * 50).toString());
    });
});


@keyframes number-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.05); color: #0066cc; }
}


/* ── Rainbow effect для анімації чисел ── */
@keyframes rainbow {
    0% { color: #003d82; }
    25% { color: #0066cc; }
    50% { color: #4a90e2; }
    75% { color: #0066cc; }
    100% { color: #003d82; }
}


.stats-panel-number.animating {
    animation: rainbow 1.5s ease-in-out;
}


/* ── Gradient title ── */
.welcome-title {
    background: linear-gradient(135deg, #003d82 0%, #0066cc 50%, #003d82 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    animation: gradient-shift 3s ease infinite;
    background-size: 200% 200%;
}


/* ══════════════════════════════════════════════
@keyframes gradient-shift {
  MODERN UI: Particles.js фон + прогрес скролла
    0%, 100% { background-position: 0% 50%; }
══════════════════════════════════════════════ */
    50% { background-position: 100% 50%; }
}
 
/* ── Smooth reveal для карточок ── */
.category-card {
    /* AOS сам додає opacity при ініціалізації */
}
 
/* ── Неоморфізм для випадкових статей ── */
.random-article-card {
    background: linear-gradient(145deg, #ffffff, #f0f6ff);
    box-shadow:
        8px 8px 16px rgba(0, 61, 130, 0.08),
        -8px -8px 16px rgba(255, 255, 255, 0.9);
    border: none !important;
}
 
.random-article-card:hover {
    box-shadow:
        12px 12px 24px rgba(0, 61, 130, 0.12),
        -12px -12px 24px rgba(255, 255, 255, 1);
    background: linear-gradient(145deg, #f0f6ff, #ffffff);
}


/* ── 1. Прогрес скролла ── */
/* ── Glassmorphism для заголовків ── */
mw.hook('wikipage.content').add(function() {
.section-categories {
     if (mw.config.get('wgPageName') !== 'Головна_сторінка') return;
     text-shadow: 0 2px 8px rgba(0, 61, 130, 0.1);
   
}
    // Створюємо індикатор
    var progressBar = document.createElement('div');
    progressBar.className = 'scroll-progress';
    document.body.appendChild(progressBar);
   
    function updateProgress() {
        var winScroll = document.documentElement.scrollTop || document.body.scrollTop;
        var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
        var scrolled = (winScroll / height) * 100;
        progressBar.style.width = scrolled + '%';
    }
   
    window.addEventListener('scroll', updateProgress);
    updateProgress();
});


/* ── 2. Particles.js canvas фон ── */
/* ── Gradient підкреслення ── */
mw.hook('wikipage.content').add(function() {
.section-categories::after {
    if (mw.config.get('wgPageName') !== 'Головна_сторінка') return;
     background: linear-gradient(90deg, #ffd700, #ffed4e, #ffd700) !important;
   
     box-shadow: 0 2px 8px rgba(255, 215, 0, 0.4);
    var welcomeWrapper = document.querySelector('.welcome-wrapper');
}
    if (!welcomeWrapper) return;
   
    // Створюємо canvas
    var canvas = document.createElement('canvas');
    canvas.className = 'particles-canvas';
    canvas.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:0;';
      
    // Gradient mask для плавного переходу по краях
    canvas.style.webkitMaskImage = 'linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 10%, rgba(0,0,0,1) 90%, rgba(0,0,0,0) 100%), linear-gradient(to right, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 10%, rgba(0,0,0,1) 90%, rgba(0,0,0,0) 100%)';
    canvas.style.maskImage = 'linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 10%, rgba(0,0,0,1) 90%, rgba(0,0,0,0) 100%), linear-gradient(to right, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 10%, rgba(0,0,0,1) 90%, rgba(0,0,0,0) 100%)';
     canvas.style.webkitMaskComposite = 'source-in';
    canvas.style.maskComposite = 'intersect';
    welcomeWrapper.style.position = 'relative';
    welcomeWrapper.insertBefore(canvas, welcomeWrapper.firstChild);
   
    var ctx = canvas.getContext('2d');
    canvas.width = welcomeWrapper.offsetWidth;
    canvas.height = welcomeWrapper.offsetHeight;
   
    var particles = [];
    var particleCount = 40;
    var mouse = { x: null, y: null, radius: 100 };
   
    // Частинки
    function Particle() {
        this.x = Math.random() * canvas.width;
        this.y = Math.random() * canvas.height;
        this.vx = (Math.random() - 0.5) * 0.5;
        this.vy = (Math.random() - 0.5) * 0.5;
        this.radius = Math.random() * 2 + 1;
    }
   
    Particle.prototype.draw = function() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
        ctx.fillStyle = 'rgba(255, 215, 0, 0.6)';
        ctx.fill();
    };
   
    Particle.prototype.update = function() {
        if (this.x > canvas.width || this.x < 0) this.vx = -this.vx;
        if (this.y > canvas.height || this.y < 0) this.vy = -this.vy;
       
        this.x += this.vx;
        this.y += this.vy;
       
        this.draw();
    };
   
    // Ініціалізація
    for (var i = 0; i < particleCount; i++) {
        particles.push(new Particle());
    }
   
    // Анімація
    function animate() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
       
        for (var i = 0; i < particles.length; i++) {
            particles[i].update();
           
            // З'єднання лініями
            for (var j = i + 1; j < particles.length; j++) {
                var dx = particles[i].x - particles[j].x;
                var dy = particles[i].y - particles[j].y;
                var distance = Math.sqrt(dx * dx + dy * dy);
               
                if (distance < 120) {
                    ctx.beginPath();
                    ctx.strokeStyle = 'rgba(255, 215, 0, ' + (1 - distance / 120) * 0.3 + ')';
                    ctx.lineWidth = 1;
                    ctx.moveTo(particles[i].x, particles[i].y);
                    ctx.lineTo(particles[j].x, particles[j].y);
                    ctx.stroke();
                }
            }
        }
       
        requestAnimationFrame(animate);
    }
   
    animate();
   
    // Resize
    window.addEventListener('resize', function() {
        canvas.width = welcomeWrapper.offsetWidth;
        canvas.height = welcomeWrapper.offsetHeight;
    });
});

Версія за 20:22, 16 лютого 2026

/* ── Заголовок сторінки ── */
#firstHeading {
    font-size: clamp(28px, 4vw, 48px);
}

/* ── Бокове меню ── */
#mw-panel {
    font-size: clamp(14px, 1.2vw, 18px);
}

/* ── Прибираємо обмеження Vector ── */
body.skin-vector-2022 .mw-page-container-inner,
body.skin-vector .mw-content-container,
body.skin-vector .vector-body,
body.skin-vector #bodyContent {
    max-width: none !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}

body.skin-vector-2022 .mw-body,
body.skin-vector-2022 .mw-body-content {
    max-width: none !important;
    margin: 0 !important;
}

/* ════════════════════════════════════
   ПРИВІТАННЯ + СТАТИСТИКА
═══════════════════════════════════════ */
.welcome-wrapper {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
    padding: 40px 5vw 40px;
    box-sizing: border-box;
    width: 100%;
}

.welcome-text {
    flex: 1;
    text-align: center;
    /* Зміщуємо центр тексту компенсуючи ширину панелі статистики */
    transform: translateX(-80px);
}

.welcome-subtitle {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 1.45rem;
    font-weight: 400;
    color: #444;
    letter-spacing: 0.6px;
    margin-bottom: 10px;
    opacity: 0.92;
}

.welcome-title {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 2.45rem;
    font-weight: 700;
    line-height: 1.18;
    color: #003d82;
    letter-spacing: -0.3px;
    margin: 0;
}

/* ── Панель статистики (справа від привітання) ── */
.stats-panel {
    width: 260px;
    flex-shrink: 0;
    background: white;
    border-radius: 16px;
    border: 1px solid rgba(0,61,130,0.08);
    box-shadow: 0 6px 24px rgba(0,0,0,0.07);
    overflow: hidden;
}

.stats-panel-header {
    background: rgba(210, 230, 255, 0.35);
    color: #003d82;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 1rem;
    font-weight: 700;
    padding: 12px 18px;
    border-bottom: 1px solid rgba(0,61,130,0.1);
}

.stats-panel-list {
    padding: 4px 0;
}

.stats-panel-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 18px;
    border-bottom: 1px solid rgba(0,61,130,0.05);
    transition: background 0.2s;
}

.stats-panel-item:last-child {
    border-bottom: none;
}

.stats-panel-item:hover {
    background: rgba(210, 230, 255, 0.2);
}

.stats-panel-label {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 14px;
    color: #555;
}

.stats-panel-number {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 18px;
    font-weight: 800;
    color: #003d82;
}

/* ════════════════════════════════════
   ЗАГОЛОВОК КАТЕГОРІЙ
═══════════════════════════════════════ */
.section-categories {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 2.1rem;
    font-weight: 700;
    color: #003d82;
    text-align: center;
    margin: 30px 0 30px;
    /* Компенсуємо ширину правої колонки щоб текст був по центру сітки */
    padding: 0 calc(360px + 24px) 0 0;
    background: transparent;
    box-sizing: border-box;
}

.section-categories::after {
    content: '';
    display: block;
    width: 90px;
    height: 4px;
    background: #ffd700;
    margin: 14px auto 0;
    border-radius: 2px;
}

/* ════════════════════════════════════
   ОСНОВНИЙ LAYOUT: категорії + права колонка
═══════════════════════════════════════ */
.main-content-layout {
    display: flex;
    gap: 24px;
    align-items: flex-start;
    padding: 0 5vw;
    margin: 0 0 70px;
    box-sizing: border-box;
    width: 100%;
}

/* ── Сітка карток — 3 в ряд ── */
.category-grid-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
    flex: 1;
    min-width: 0;
}

/* ── Права колонка ── */
.right-column {
    width: 360px;
    min-width: 360px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
    align-self: flex-start;
    padding-top: 0;
}

/* ════════════════════════════════════
   КАРТКИ КАТЕГОРІЙ
═══════════════════════════════════════ */
.category-card {
    background: white;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 6px 24px rgba(0,0,0,0.08);
    transition: all 0.28s cubic-bezier(0.165, 0.84, 0.44, 1);
    cursor: pointer;
    border: 1px solid rgba(0,61,130,0.08);
    height: 100%;
    display: flex;
    flex-direction: column;
}

.category-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 20px 40px rgba(0,61,130,0.18);
    border-color: rgba(0,61,130,0.15);
}

.card-image {
    padding: 28px 0 16px;
    flex-grow: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: white;
}

.card-image img {
    width: 88px;
    height: 88px;
    object-fit: contain;
    transition: transform 0.35s ease;
}

.category-card:hover .card-image img {
    transform: scale(1.12);
}

.card-title {
    font-size: 15px;
    font-weight: 600;
    color: #003d82;
    text-align: center;
    padding: 8px 12px 12px;
    line-height: 1.4;
    flex-grow: 0;
    background: rgba(210, 230, 255, 0.15);
    border-radius: 10px;
    margin: 0 10px 14px;
}

.card-title pre {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 !important;
    font-family: inherit !important;
    font-size: inherit !important;
    font-weight: inherit !important;
    color: inherit !important;
    white-space: normal !important;
}

/* ════════════════════════════════════
   ВИПАДКОВІ СТАТТІ
═══════════════════════════════════════ */
.random-articles-panel {
    background: white;
    border-radius: 16px;
    border: 1px solid rgba(0,61,130,0.08);
    box-shadow: 0 6px 24px rgba(0,0,0,0.07);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
}



.random-articles-header {
    background: rgba(210, 230, 255, 0.35);
    color: #003d82;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 1rem;
    font-weight: 700;
    padding: 14px 18px;
    border-bottom: 1px solid rgba(0,61,130,0.1);
}

#random-articles-list {
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.random-article-card {
    display: flex;
    gap: 14px;
    padding: 14px;
    border-radius: 12px;
    background: rgba(210, 230, 255, 0.12);
    border: 1px solid rgba(0,61,130,0.07);
    text-decoration: none;
    color: inherit;
    transition: all 0.22s ease;
    align-items: flex-start;
}

.random-article-card:hover {
    background: rgba(210, 230, 255, 0.35);
    border-color: rgba(0,61,130,0.18);
    transform: translateX(3px);
    text-decoration: none;
}

.random-article-thumb {
    width: 90px;
    height: 90px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
    background: #eef2f8;
}

.random-article-thumb-placeholder {
    width: 90px;
    height: 90px;
    border-radius: 10px;
    flex-shrink: 0;
    background: linear-gradient(135deg, #e8eef7, #c8d8ee);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
}

.random-article-info {
    flex: 1;
    min-width: 0;
}

.random-article-title {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 15px;
    font-weight: 700;
    color: #003d82;
    margin-bottom: 6px;
    line-height: 1.35;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.random-article-excerpt {
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 13px;
    color: #555;
    line-height: 1.45;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

.random-articles-loading {
    padding: 20px;
    text-align: center;
    color: #888;
    font-size: 13px;
    font-family: system-ui, sans-serif;
}

.random-articles-refresh {
    display: none;
}

/* ════════════════════════════════════
   РЕСУРСИ ТА ПОСИЛАННЯ
═══════════════════════════════════════ */
.resources-and-contacts {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    margin: 30px 0 50px;
    align-items: stretch;
}

.resource-block,
.contacts-block {
    flex: 1;
    min-width: 300px;
    background: rgba(220, 235, 255, 0.18);
    border: 1px solid rgba(180, 210, 240, 0.5);
    border-radius: 14px;
    padding: 28px 32px;
    box-shadow: 0 4px 12px rgba(0,61,130,0.06);
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
}

.resource-block ul,
.contacts-block ul {
    flex: 1;
    list-style: none;
    padding-left: 0;
    margin: 0;
}

.resource-block h2,
.contacts-block h2 {
    font-size: 1.3rem !important;
    font-weight: 700 !important;
    color: #003d82 !important;
    margin: 0 0 20px 0 !important;
    padding: 0 0 14px 0 !important;
    border: none !important;
    border-bottom: 2px solid rgba(0,61,130,0.12) !important;
    line-height: 1.3 !important;
}

.resource-block li,
.contacts-block li {
    margin-bottom: 11px;
    line-height: 1.6;
    font-size: 1rem;
    color: #444;
    padding-left: 14px;
    position: relative;
}

.resource-block li::before,
.contacts-block li::before {
    content: '›';
    position: absolute;
    left: 0;
    color: #003d82;
    font-weight: 700;
    opacity: 0.5;
}

.resource-block li a,
.contacts-block li a {
    color: #1e40af;
    text-decoration: none;
    transition: color 0.2s;
}

.resource-block li a:hover,
.contacts-block li a:hover {
    color: #003d82;
    text-decoration: underline;
}

/* ════════════════════════════════════
   АДАПТИВНІСТЬ
═══════════════════════════════════════ */
@media (max-width: 1100px) {
    .welcome-wrapper {
        flex-direction: column;
        text-align: center;
    }
    .stats-panel {
        width: 100%;
        max-width: 400px;
    }
    .main-content-layout {
        flex-direction: column;
    }
    .right-column {
        width: 100%;
        min-width: unset;
        flex-direction: row;
        flex-wrap: wrap;
    }
    .category-grid-container {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (max-width: 820px) {
    .category-grid-container {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 520px) {
    .category-grid-container {
        grid-template-columns: 1fr;
    }
    .welcome-title { font-size: 2rem; }
    .welcome-subtitle { font-size: 1.25rem; }
    .section-categories { font-size: 1.8rem; }
}

@media (max-width: 900px) {
    .resources-and-contacts {
        flex-direction: column;
        gap: 20px;
    }
}

/* ── Ліва колонка з заголовком і сіткою ── */
.category-column {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.category-column .category-grid-container {
    flex: 1;
}


    .timeline-dot {
        left: -33px;
    }
    .timeline-year {
        font-size: 1.2rem;
    }
    .timeline-event {
        font-size: 14px;
    }
}





/* ══════════════════════════════════════════════
   MODERN UI: градієнти, glassmorphism, анімації
══════════════════════════════════════════════ */

/* ── Прогрес скролла ── */
.scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 4px;
    background: linear-gradient(90deg, #003d82, #0066cc, #ffd700);
    z-index: 99999;
    transition: width 0.1s ease;
    box-shadow: 0 2px 8px rgba(0, 61, 130, 0.3);
}

/* ── Градієнтний фон для welcome ── */
.welcome-wrapper {
    background: linear-gradient(180deg, 
        rgba(210, 230, 255, 0.4) 0%, 
        rgba(210, 230, 255, 0.25) 40%,
        rgba(255, 255, 255, 0) 100%);
    position: relative;
    overflow: hidden;
    padding-bottom: 60px !important;
}

/* Плавний перехід до білого фону */
.welcome-wrapper::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 80px;
    background: linear-gradient(to bottom, transparent, white);
    pointer-events: none;
    z-index: 1;
}

.welcome-text,
.stats-panel {
    position: relative;
    z-index: 2;
}

/* ── Glassmorphism для статистики ── */
.stats-panel {
    background: rgba(255, 255, 255, 0.7) !important;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.3) !important;
    box-shadow: 0 8px 32px rgba(0, 61, 130, 0.15) !important;
}

.stats-panel-header {
    background: linear-gradient(135deg, rgba(0, 61, 130, 0.1), rgba(0, 102, 204, 0.15)) !important;
}

/* ── Glassmorphism для випадкових статей ── */
.random-articles-panel {
    background: rgba(255, 255, 255, 0.75) !important;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.3) !important;
}

/* ── Градієнтні картки категорій ── */
.category-card {
    background: linear-gradient(135deg, #ffffff 0%, #f8fbff 100%);
    border: 1px solid rgba(0, 61, 130, 0.08);
    position: relative;
    overflow: hidden;
}

.category-card::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: linear-gradient(135deg, transparent, rgba(0, 61, 130, 0.05), transparent);
    transform: rotate(45deg);
    transition: all 0.6s ease;
    opacity: 0;
}

.category-card:hover::before {
    opacity: 1;
    top: -25%;
    left: -25%;
}

/* ── Мікроанімації: bounce для іконок ── */
.category-card:hover .card-image img {
    animation: icon-bounce 0.6s ease;
}

@keyframes icon-bounce {
    0%, 100% { transform: scale(1.12) translateY(0); }
    50% { transform: scale(1.12) translateY(-8px); }
}

/* ── Gradient hover для карточок ── */
.category-card {
    transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
}

.category-card:hover {
    transform: translateY(-8px) scale(1.02);
    box-shadow: 0 24px 48px rgba(0, 61, 130, 0.2);
}

/* ── Pulse для чисел статистики ── */
.stats-panel-number {
    animation: number-pulse 2s ease-in-out infinite;
}

@keyframes number-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.05); color: #0066cc; }
}

/* ── Rainbow effect для анімації чисел ── */
@keyframes rainbow {
    0% { color: #003d82; }
    25% { color: #0066cc; }
    50% { color: #4a90e2; }
    75% { color: #0066cc; }
    100% { color: #003d82; }
}

.stats-panel-number.animating {
    animation: rainbow 1.5s ease-in-out;
}

/* ── Gradient title ── */
.welcome-title {
    background: linear-gradient(135deg, #003d82 0%, #0066cc 50%, #003d82 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    animation: gradient-shift 3s ease infinite;
    background-size: 200% 200%;
}

@keyframes gradient-shift {
    0%, 100% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
}

/* ── Smooth reveal для карточок ── */
.category-card {
    /* AOS сам додає opacity при ініціалізації */
}

/* ── Неоморфізм для випадкових статей ── */
.random-article-card {
    background: linear-gradient(145deg, #ffffff, #f0f6ff);
    box-shadow: 
        8px 8px 16px rgba(0, 61, 130, 0.08),
        -8px -8px 16px rgba(255, 255, 255, 0.9);
    border: none !important;
}

.random-article-card:hover {
    box-shadow: 
        12px 12px 24px rgba(0, 61, 130, 0.12),
        -12px -12px 24px rgba(255, 255, 255, 1);
    background: linear-gradient(145deg, #f0f6ff, #ffffff);
}

/* ── Glassmorphism для заголовків ── */
.section-categories {
    text-shadow: 0 2px 8px rgba(0, 61, 130, 0.1);
}

/* ── Gradient підкреслення ── */
.section-categories::after {
    background: linear-gradient(90deg, #ffd700, #ffed4e, #ffd700) !important;
    box-shadow: 0 2px 8px rgba(255, 215, 0, 0.4);
}