Анализ сайта portoatemorrer.com
Основное Готовность: 100%
Домен
portoatemorrer.com
Состояние доменного имени
?
Проверяем корректность доменного имени и наличие технических проблем на уровне домена.
Длина домена велика. Но если вы продвигаете запрос, входящий в название домена, то это хорошо.
Домен второго уровня идеален для продвижения.
Ответ сервера
200 Успешный ответ
HTTP-код ответа и цепочка редиректов
?
Код 200 — страница доступна. Коды 3xx — редиректы (цепочки замедляют загрузку и размывают ссылочный вес). Коды 4xx/5xx — ошибки, поисковик не сможет проиндексировать страницу.
Сервер настроен корректно.
Цепочка редиректов:
http://portoatemorrer.com
301 MovedPermanently
https://portoatemorrer.com/
200 OK
Безопасность
Сайт безопасен
Использование HTTPS и SSL-сертификат
?
HTTPS — обязательный стандарт. Google и Яндекс отдают предпочтение защищённым сайтам. Отсутствие SSL или просроченный сертификат ведут к предупреждениям в браузере и снижению позиций.
Не настроен HSTS (Strict-Transport-Security) — рекомендуется включить.
На сайте работает защищенный протокол ssl и сайт открывается по https.
Ssl-сертификат действителен до 28.09.2026 16:54:47.
HTTP автоматически перенаправляется на HTTPS.
Поздравляем! Сайт не содержится в реестре РКН.
Кодировка
UTF-8
Кодировка символов страницы
?
Стандарт — UTF-8. Неправильная кодировка вызывает нечитаемые символы и мешает поисковику корректно распознать текст страницы.
Указана кодировка на странице UTF-8.
Язык
pt-PT
Атрибут lang в HTML-теге
?
Атрибут lang (<html lang="ru">) сообщает поисковикам и браузерам, на каком языке написана страница. Помогает при ранжировании в региональном поиске.
Язык документа указан явно: pt-PT.
Скорость загрузки
~0,62сек
Время отклика сервера (TTFB)
?
Time To First Byte — время до получения первого байта от сервера. Норма до 200 мс. Медленный отклик ухудшает пользовательский опыт и ранжирование: Яндекс и Google учитывают скорость страниц.
Скорость загрузки сайта 0,62сек оптимальна.
Объем документа
164Кб
Размер HTML-кода страницы
?
Слишком большой HTML замедляет парсинг браузером и сканирование поисковым роботом. Рекомендуется не более 200 Кб.
Объем html-документа 164Кб оптимален.
Структура html-документа корректна.
Ресурсы
Ресурсы: 4
Внешние ресурсы страницы (CSS, JS, изображения)
?
Количество и тип подключённых ресурсов влияют на скорость загрузки. Большое число запросов увеличивает время рендеринга страницы.
Кол-во файлов ресурсов 4 достаточно.
Показать полный список ресурсов
| Тип | Название | Значение |
|---|---|---|
| stylesheet | https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,400;0,600;0,700;0,800;0,900;1,700&family=Inter:wght@300;400;500;600;700&display=swap | |
| stylesheet | https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css | |
| js | https://unpkg.com/lucide@latest/dist/umd/lucide.min.js | |
| js | https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2185320483550230 |
Серверные заголовки
Кол-во: 4
HTTP-заголовки ответа сервера
?
Заголовки сервера передают браузеру и поисковику служебную информацию: кеширование, безопасность (CSP, HSTS), сжатие (gzip). Правильная настройка ускоряет загрузку и повышает защищённость.
Найдены серверные заголовки 4шт. Подробнее про серверные заголовки.
Показать полный список серверных заголовков
| Ключ | Значение |
|---|---|
| Server | nginx/1.28.0 |
| Date | Fri, 21 Aug 2026 16:57:04 GMT |
| Connection | keep-alive |
| Cache-Control | public, max-age=3600 |
CMS
Не определена
Система управления сайтом (движок)
?
CMS — это движок, на котором работает сайт (WordPress, 1C-Bitrix, Tilda и др.). Знание CMS помогает понять возможности SEO-оптимизации и подобрать подходящие инструменты. «Не определена» — вероятно, самописный сайт или нестандартная сборка.
CMS не определена. Вероятно, сайт самописный либо движок надёжно скрыт. Это не ошибка.
Веб-сервер
Программное обеспечение сервера
?
Веб-сервер — это ПО, которое отдаёт страницы посетителям (nginx, Apache, IIS, LiteSpeed и др.). Определяется по серверным заголовкам ответа (Server, X-Powered-By и т.п.). «Не определён» — сервер намеренно скрывает эти заголовки, это нормальная практика безопасности.
Сайт работает на веб-сервере nginx.
Мета-теги Готовность: 32%
Title
Porto Até Morrer — A Voz do Dragão
Заголовок страницы в браузере и поисковой выдаче
?
Title — главный SEO-заголовок страницы. Влияет на CTR в поиске и ранжирование. Оптимальная длина: 50–70 символов. Ключевые слова — ближе к началу.
Необходимо увеличить число символов в title (текущее значение: 34, оптимально: от 40 до 45)
Дублей словоформ в title не найдено.
Description
O site que te atualiza 24 sobre 24 horas sobre toda a atualidade do FC Porto
Описание страницы в поисковой выдаче (сниппет)
?
Meta Description — текст под заголовком в выдаче. Напрямую на позиции не влияет, но влияет на CTR. Оптимальная длина: 120–160 символов.
Необходимо увеличить число символов в description (текущее значение мало: 76, минимум: 80, оптимально: от 120 до 130)
Keywords
Список ключевых слов страницы (устаревший тег)
?
Meta Keywords не учитывается Яндексом и Google для ранжирования с 2009–2012 годов. Заполнение не обязательно, но не вредит. Конкурент может использовать содержимое для анализа.
Установите мета-тег keywords!
Канонический Url
Указывает поисковику основную версию страницы
?
Canonical (rel=canonical) предотвращает проблему дублей страниц. Должен точно совпадать с URL проверяемой страницы. Неправильный canonical может передать ссылочный вес на другую страницу.
Рекомендуем прописать канонический Url.
Robots
Ошибок нет
Директивы для поисковых роботов на уровне страницы
?
Meta Robots управляет индексацией конкретной страницы: index/noindex — индексировать ли, follow/nofollow — следовать ли по ссылкам. Noindex полностью исключает страницу из поиска.
Meta-тег robots не указан. Страница свободна для индексации.
Адаптивность
width=device-width, initial-scale=1.0
Настройка масштабирования на мобильных устройствах
?
Тег viewport (<meta name="viewport">) сообщает браузеру, как масштабировать страницу на мобильных. Стандарт: width=device-width, initial-scale=1. Отсутствие — признак отсутствия мобильной версии.
Meta-тег viewport со значением-константой width=device-width задаёт ширину страницы в соответствии с размером экрана.
Meta-тег viewport со значением initial-scale=1.0 определяет масштаб 1:1, т.е. «не масштабировать».
Разметка OpenGraph
Не найдено
Мета-теги для красивых превью в соцсетях
?
OpenGraph (og:title, og:description, og:image) управляет тем, как страница выглядит при репосте в социальных сетях и мессенджерах. Отсутствие OG-тегов — невзрачный превью при шеринге.
Разметка OpenGraph не задана. Страница не оптимизирована под социальные сети. Мета-теги с разметкой Og помогают социальным роботам лучше структурировать Ваш сайт.
Все мета-теги
Кол-во: 2
Полный список мета-тегов страницы
?
Таблица всех meta-тегов, включая нестандартные. Позволяет найти опечатки, дубли и лишние теги.
Найдены мета-теги 2шт. Мета-теги не видимы для человека и предназначены для обмена информацией между веб-страницей и поисковыми системами, браузерами и другими веб-службами. С ними роботы 🤖 и устройства ведут себя более ожидаемо.
Показать полный список мета-тегов
| Тип | Название | Значение |
|---|---|---|
| name | viewport | width=device-width, initial-scale=1.0 |
| name | description | O site que te atualiza 24 sobre 24 horas sobre toda a atualidade do FC Porto |
Оптимизация Готовность: 90%
Структура
Ошибок нет
Семантические HTML-элементы страницы
?
Проверяет наличие основных структурных элементов: nav, header, footer, main. Корректная семантическая структура помогает поисковику понять архитектуру страницы.
Структура документа корректна (теги <html> и <body> присутствуют в единственном экземпляре).
Контент
Ошибок нет
Объём и качество текстового содержимого
?
Анализирует объём полезного текста на странице. Слишком мало — страница может считаться малополезной. Слишком много — ухудшается читаемость и восприятие.
Слова из title 8 встречаются в тексте достаточно.
Абзацев с текстом 22 достаточно.
Среднее число слов в абзаце 26 достаточно.
Кол-во знаков контента 9923 на странице оптимально.
Кол-во слов 1743 на странице оптимально.
Заголовки
Ошибок нет
Иерархия заголовков H1–H6
?
H1 должен быть один и содержать ключевой запрос. H2–H6 описывают подразделы. Пропуск уровней (H1 → H3) и несколько H1 — типичные ошибки, снижающие понятность страницы для поисковика.
На странице присутствуют заголовки <h1> 6. Это прекрасно.
На странице присутствуют заголовки <h2> 4. Это хорошо.
Тошнота
4,90
Насколько одно слово доминирует в тексте
?
Классическая тошнота = √(частота самого повторяющегося слова). Норма до 7–8: текст воспринимается естественно. Выше — поисковик может счесть страницу переспамленной.
Тошнота превышает норму 3. Измените текст страницы!
Академич. тошнота
10,56%
Насколько текст перенасыщен ключевыми словами
?
Академическая тошнота = (частота слова / общее количество слов) × 100%. Показывает долю конкретного слова в тексте. Норма 5–15%.
Академическая тошнота страницы в пределах нормы.
Семантическое ядро
20
Наиболее часто встречающиеся слова на странице
?
Топ слов по частоте использования. Показывает, какие слова доминируют в тексте с точки зрения поисковика.
Контент страницы содержит осмысленный текст и слова.
Показать список слов
| Слово | Кол-во | Частота |
|---|---|---|
| portugal | 24 | 1,38% |
| sugestão: | 13 | 0,75% |
| notícias | 11 | 0,63% |
| empréstimo | 10 | 0,57% |
| nacionais | 9 | 0,52% |
| ganhou | 9 | 0,52% |
| carregar | 8 | 0,46% |
| extremo | 8 | 0,46% |
| modalidades | 7 | 0,40% |
| espanha | 7 | 0,40% |
| defesa | 7 | 0,40% |
| central | 7 | 0,40% |
| betclic | 6 | 0,34% |
| campeões | 6 | 0,34% |
| jornal | 6 | 0,34% |
| futebol | 5 | 0,29% |
| jornais | 5 | 0,29% |
| aposta | 5 | 0,29% |
| oficial | 5 | 0,29% |
| 2025/26 | 5 | 0,29% |
Индексация Готовность: 30%
Индексирование
Ошибок нет
Разрешено ли индексирование страницы
?
Проверяет, не закрыта ли страница от индексации через robots.txt, meta robots или X-Robots-Tag. Страница, закрытая от индексации, не появится в поисковой выдаче.
Анкоров на странице 47 оптимально. Поисковые роботы обязательно проиндексируют сайт.
Robots.txt
Найден корректный robots.txt
Файл управления сканированием сайта роботами
?
Robots.txt указывает поисковым роботам, какие страницы сканировать, а какие — нет. Ошибки в файле могут случайно закрыть важные разделы от индексации.
Robots.txt настроен корректно. Размер файла: 168593 байт. Загружен за: 1сек.
Проверяемая страница не запрещена в robots.txt.
Robots.txt доступен по постоянному адресу
Цепочка редиректов для файла robots.txt:
http://portoatemorrer.com/robots.txt
301 MovedPermanently
https://portoatemorrer.com/robots.txt
200 OK
Показать содержимое robots.txt
<!DOCTYPE html>
<html lang="pt-PT">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Porto Até Morrer — A Voz do Dragão</title>
<meta name="description" content="O site que te atualiza 24 sobre 24 horas sobre toda a atualidade do FC Porto">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,400;0,600;0,700;0,800;0,900;1,700&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js" defer></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
/* === RESET & BASE === */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--bg: #070B14;
--bg-1: #0B1220;
--bg-2: #0F1826;
--bg-card: #111D2E;
--border: rgba(255,255,255,0.06);
--border-h: rgba(255,255,255,0.13);
--blue: #1A4FFF;
--blue-2: #3B6FFF;
--blue-3: #0038CC;
--blue-gl: rgba(26,79,255,0.28);
--blue-gl2: rgba(26,79,255,0.11);
--gold: #F0B030;
--gold-gl: rgba(240,176,48,0.18);
--red: #FF3344;
--green: #22D47E;
--text: #E8EEFF;
--text-2: #7D90BB;
--text-3: #3D4E70;
--r: 12px;
--r-lg: 20px;
--fw: 1300px;
--gap: 20px;
--fh: 'Barlow Condensed', sans-serif;
--fb: 'Inter', sans-serif;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--fb);
background: var(--bg);
color: var(--text);
line-height: 1.6;
overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
img { max-width: 100%; height: auto; display: block; }
button { cursor: pointer; border: none; background: none; font-family: inherit; }
/* === UTILITIES === */
.container { max-width: var(--fw); margin: 0 auto; padding: 0 24px; }
.badge {
display: inline-flex; align-items: center; gap: 5px;
padding: 3px 10px; border-radius: 99px;
font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
text-transform: uppercase;
}
.badge-blue { background: var(--blue-gl2); color: var(--blue-2); border: 1px solid rgba(59,111,255,0.3); }
.badge-red { background: rgba(255,51,68,0.12); color: var(--red); border: 1px solid rgba(255,51,68,0.28); }
.badge-gold { background: var(--gold-gl); color: var(--gold); border: 1px solid rgba(240,176,48,0.28); }
.badge-green { background: rgba(34,212,126,0.1); color: var(--green); border: 1px solid rgba(34,212,126,0.22); }
.badge-dark { background: rgba(255,255,255,0.05); color: var(--text-2); border: 1px solid var(--border); }
.live-dot {
width: 7px; height: 7px; border-radius: 50%;
background: currentColor; display: inline-block;
animation: blink 1.3s ease-in-out infinite;
flex-shrink: 0;
}
.badge-red .live-dot { background: var(--red); }
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
/* === SQUAD / PLANTEL === */
.squad-filter { background: var(--bg-card); border: 1px solid var(--border); color: var(--text-2); border-radius: 99px; padding: 7px 18px; font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.18s; font-family: var(--fb); }
.squad-filter:hover { border-color: var(--blue-2); color: var(--text); }
.squad-filter.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.squad-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
@media (max-width: 1100px) { .squad-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 820px) { .squad-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 540px) { .squad-grid { grid-template-columns: repeat(2, 1fr); } }
.squad-card {
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg);
overflow: hidden; cursor: default; transition: transform 0.2s, box-shadow 0.2s, background 0.2s, border-color 0.2s;
position: relative;
}
.squad-card:hover {
transform: translateY(-4px);
background: linear-gradient(160deg, #0d1e40, #0a1630);
border-color: var(--blue-2);
box-shadow: 0 8px 32px rgba(26,79,255,0.25);
}
.squad-num {
font-family: var(--fh); font-size: 42px; font-weight: 900; color: var(--blue);
line-height: 1; padding: 14px 14px 0; opacity: 0.85;
transition: color 0.2s;
}
.squad-card:hover .squad-num { color: var(--blue-2); opacity: 1; }
.squad-photo { padding: 4px 8px 0; height: 220px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.squad-photo img { width: 100%; height: 100%; object-fit: contain; object-position: center; }
.sq-init { font-family: var(--fh); font-size: 36px; font-weight: 900; color: var(--text-3); }
.squad-flag { height: 16px; border-radius: 2px; vertical-align: middle; box-shadow: 0 1px 3px rgba(0,0,0,0.4); }
.squad-info { padding: 10px 14px 14px; }
.squad-name { font-family: var(--fh); font-size: 15px; font-weight: 800; color: var(--text); line-height: 1.2; margin-bottom: 6px; }
.squad-meta { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.squad-pos-badge { font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.07em; padding: 2px 7px; border-radius: 99px; }
.squad-pos-badge.gr { background: rgba(240,176,48,0.15); color: var(--gold); border: 1px solid rgba(240,176,48,0.3); }
.squad-pos-badge.def { background: rgba(26,79,255,0.15); color: var(--blue-2); border: 1px solid rgba(26,79,255,0.3); }
.squad-pos-badge.med { background: rgba(34,212,126,0.12); color: var(--green); border: 1px solid rgba(34,212,126,0.3); }
.squad-pos-badge.av { background: rgba(255,60,60,0.12); color: #ff6060; border: 1px solid rgba(255,60,60,0.3); }
.squad-stats { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-3); max-height: 0; overflow: hidden; opacity: 0; transition: max-height 0.25s, opacity 0.25s; }
.squad-card:hover .squad-stats { max-height: 30px; opacity: 1; }
.squad-stat-sep { color: var(--text-3); opacity: 0.4; }
.squad-card:hover .squad-stats span:not(.squad-stat-sep) { color: var(--text-2); font-weight: 600; }
/* === CALENDAR PAGE === */
.cal-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 24px; }
.cal-filter { background: var(--bg-card); border: 1px solid var(--border); border-radius: 99px; padding: 6px 16px; font-size: 12px; font-weight: 700; color: var(--text-2); cursor: pointer; transition: all 0.2s; }
.cal-filter.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.cal-filter:hover:not(.active) { border-color: var(--blue-2); color: var(--text); }
.cal-month { font-family: var(--fh); font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-3); padding: 18px 0 8px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.cal-row { display: grid; grid-template-columns: 90px 28px 1fr auto 1fr 36px; align-items: center; gap: 10px; padding: 10px 14px; border-radius: var(--r); border: 1px solid transparent; margin-bottom: 4px; transition: background 0.15s, border-color 0.15s; cursor: default; }
.cal-row:hover { background: var(--bg-card); border-color: var(--border); }
.cal-row.result-V { border-left: 3px solid var(--green) !important; }
.cal-row.result-E { border-left: 3px solid var(--gold) !important; }
.cal-row.result-D { border-left: 3px solid #ff4444 !important; }
.cal-row.next-game { border: 1px solid var(--blue-2); background: linear-gradient(90deg, rgba(26,79,255,0.08), transparent); }
.cal-date { font-size: 11px; color: var(--text-3); font-weight: 600; line-height: 1.3; }
.cal-comp-icon { width: 22px; height: 22px; object-fit: contain; opacity: 0.85; }
.cal-team { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--text); }
.cal-team.away { flex-direction: row-reverse; text-align: right; }
.cal-team-badge { width: 24px; height: 24px; object-fit: contain; }
.cal-score { text-align: center; font-family: var(--fh); font-size: 18px; font-weight: 900; color: var(--text); letter-spacing: 1px; min-width: 52px; }
.cal-score.upcoming { font-size: 13px; font-weight: 700; color: var(--text-3); }
.cal-result { width: 28px; height: 28px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 900; flex-shrink: 0; }
.cal-result.V { background: rgba(34,212,126,0.15); color: var(--green); }
.cal-result.E { background: rgba(240,176,48,0.15); color: var(--gold); }
.cal-result.D { background: rgba(255,68,68,0.15); color: #ff6060; }
.cal-result.next { background: rgba(26,79,255,0.15); color: var(--blue-2); font-size: 8px; font-weight: 800; letter-spacing: 0.05em; }
@media (max-width: 640px) {
.cal-row { grid-template-columns: 70px 22px 1fr auto 1fr 28px; gap: 6px; padding: 8px 10px; }
.cal-team { font-size: 11px; gap: 5px; }
.cal-score { font-size: 15px; min-width: 42px; }
}
/* === BETCLIC PARTNERSHIP === */
:root { --bc: #E4002B; --bc-2: #FF1744; --bc-gl: rgba(228,0,43,0.18); --bc-gl2: rgba(228,0,43,0.08); }
.betclic-hero { background: linear-gradient(135deg, #0e0005 0%, #1a0009 50%, #0e0005 100%); border-bottom: 2px solid var(--bc); }
.betclic-hero .page-hero-icon { filter: none; }
.betclic-hero h1 span { color: var(--bc); }
.betclic-spon-badge { display: inline-flex; align-items: center; gap: 7px; background: var(--bc); color: #fff; font-size: 10px; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; padding: 4px 14px; border-radius: 99px; margin-bottom: 14px; }
.betclic-wordmark { font-family: var(--fh); font-size: 38px; font-weight: 900; color: var(--bc); letter-spacing: -0.01em; line-height: 1; margin-bottom: 6px; }
.betclic-wordmark span { color: var(--text-2); font-size: 14px; font-weight: 500; display: block; letter-spacing: 0; font-family: var(--fb); margin-top: 2px; }
.betclic-exclusive-card { background: var(--bg-card); border: 1px solid var(--bc); border-radius: var(--r-lg); overflow: hidden; box-shadow: 0 0 48px var(--bc-gl); }
.betclic-exclusive-hd { background: var(--bc); padding: 14px 22px; display: flex; align-items: center; justify-content: space-between; }
.betclic-exclusive-title { font-family: var(--fh); font-size: 15px; font-weight: 800; color: #fff; text-transform: uppercase; letter-spacing: 0.07em; }
.betclic-exclusive-sub { font-size: 11px; color: rgba(255,255,255,0.75); font-weight: 600; }
.betclic-odds-grid { display: flex; gap: 10px; padding: 22px 20px 0; }
.betclic-odd-box { flex: 1; background: var(--bg-2); border: 1px solid var(--bc-gl); border-radius: var(--r); padding: 16px 10px; text-align: center; }
.betclic-odd-lbl { font-size: 11px; color: var(--text-3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 6px; }
.betclic-odd-val { font-family: var(--fh); font-size: 32px; font-weight: 900; color: var(--bc); line-height: 1; }
.betclic-pick-row { padding: 18px 20px; background: var(--bc-gl2); border-top: 1px solid var(--bc-gl); display: flex; align-items: center; gap: 12px; }
.betclic-pick-txt { flex: 1; }
.betclic-pick-label { font-size: 11px; color: var(--text-3); font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; }
.betclic-pick-val { font-family: var(--fh); font-size: 17px; font-weight: 800; color: var(--text); margin-top: 2px; }
.betclic-pick-odd { font-family: var(--fh); font-size: 28px; font-weight: 900; color: var(--bc); flex-shrink: 0; }
.betclic-cta { display: flex; align-items: center; justify-content: center; gap: 10px; background: var(--bc); color: #fff; font-family: var(--fh); font-size: 20px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; padding: 18px 32px; border-radius: 0 0 var(--r-lg) var(--r-lg); cursor: pointer; transition: background 0.2s, transform 0.15s; text-decoration: none; width: 100%; border: none; margin-top: 0; }
.betclic-cta:hover { background: var(--bc-2); transform: translateY(-1px); }
.betclic-bonus { background: var(--bc-gl2); border: 1px solid var(--bc-gl); border-radius: var(--r); padding: 18px 22px; display: flex; align-items: center; gap: 16px; margin: 24px 0 0; }
.betclic-bonus-icon { font-size: 30px; flex-shrink: 0; }
.betclic-bonus-title { font-family: var(--fh); font-size: 16px; font-weight: 800; color: var(--bc); text-transform: uppercase; letter-spacing: 0.03em; }
.betclic-bonus-sub { font-size: 13px; color: var(--text-2); margin-top: 3px; }
.betclic-bonus-badge { background: var(--bc); color: #fff; font-size: 11px; font-weight: 800; padding: 3px 10px; border-radius: 99px; white-space: nowrap; flex-shrink: 0; }
.betclic-partner-note { text-align: center; font-size: 11px; color: var(--text-3); padding: 18px 0 0; border-top: 1px solid var(--border); margin-top: 32px; }
.nav-betclic-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--bc); margin-right: 5px; vertical-align: middle; position: relative; top: -1px; animation: blink 1.8s ease-in-out infinite; }
/* === TOP BAR === */
.topbar {
background: var(--bg-1);
border-bottom: 1px solid var(--border);
padding: 7px 0;
font-size: 12px;
color: var(--text-2);
}
.topbar .container { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.topbar-left { display: flex; align-items: center; gap: 16px; }
.topbar-right { display: flex; align-items: center; gap: 12px; }
.topbar-socials { display: flex; align-items: center; gap: 10px; }
.topbar-socials a { color: var(--text-3); transition: color 0.2s; display: flex; }
.topbar-socials a:hover { color: var(--blue-2); }
.topbar-date { color: var(--text-3); }
/* === NAVBAR === */
.navbar {
position: sticky; top: 0; z-index: 1000;
background: rgba(7, 11, 20, 0.88);
backdrop-filter: blur(22px);
-webkit-backdrop-filter: blur(22px);
border-bottom: 1px solid var(--border);
transition: background 0.3s;
}
.navbar .container { display: flex; align-items: center; gap: 28px; height: 64px; }
.nav-logo { display: flex; align-items: center; gap: 11px; flex-shrink: 0; }
.nav-logo-icon {
width: 48px; height: 48px; border-radius: 11px;
overflow: hidden;
flex-shrink: 0;
box-shadow: 0 0 22px var(--blue-gl);
}
.nav-logo-icon img {
width: 100%; height: 100%; object-fit: cover;
}
.nav-logo-text {
font-family: var(--fh); font-weight: 900;
font-size: 20px; letter-spacing: -0.01em; color: var(--text); line-height: 1.1;
}
.nav-logo-text span { color: var(--blue-2); }
.nav-logo-sub { font-size: 10px; color: var(--text-3); letter-spacing: 0.12em; text-transform: uppercase; }
.nav-links { display: flex; align-items: center; gap: 2px; flex: 1; list-style: none; }
.nav-links a {
padding: 7px 13px; border-radius: 8px;
font-size: 14px; font-weight: 500; color: var(--text-2);
transition: color 0.2s, background 0.2s; white-space: nowrap;
}
.nav-links a:hover { color: var(--text); background: rgba(255,255,255,0.05); }
.nav-links a.active { color: var(--blue-2); background: var(--blue-gl2); }
.nav-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.btn-icon {
width: 38px; height: 38px; border-radius: 10px;
background: rgba(255,255,255,0.05); color: var(--text-2);
display: flex; align-items: center; justify-content: center;
transition: background 0.2s, color 0.2s;
}
.btn-icon:hover { background: rgba(255,255,255,0.09); color: var(--text); }
.btn-live {
display: flex; align-items: center; gap: 7px;
padding: 8px 15px; border-radius: 10px;
background: rgba(255,51,68,0.1); color: var(--red);
border: 1px solid rgba(255,51,68,0.22);
font-size: 13px; font-weight: 600;
transition: background 0.2s;
}
.btn-live:hover { background: rgba(255,51,68,0.18); }
.btn-hamburger {
display: none; width: 38px; height: 38px; border-radius: 10px;
background: rgba(255,255,255,0.05); flex-direction: column;
align-items: center; justify-content: center; gap: 5px; color: var(--text-2);
}
.btn-hamburger span {
display: block; width: 18px; height: 2px;
background: currentColor; border-radius: 2px;
transition: transform 0.3s, opacity 0.3s;
}
/* === TICKER === */
.ticker {
background: linear-gradient(90deg, var(--blue-3), var(--blue));
padding: 9px 0; overflow: hidden; position: relative;
}
.ticker::before, .ticker::after {
content: ''; position: absolute; top: 0; width: 100px; height: 100%; z-index: 2;
}
.ticker::before { left: 0; background: linear-gradient(to right, var(--blue-3), transparent); }
.ticker::after { right: 0; background: linear-gradient(to left, var(--blue), transparent); }
.ticker-label {
position: absolute; left: 0; top: 0; bottom: 0;
background: rgba(0,0,0,0.3); z-index: 3;
display: flex; align-items: center; padding: 0 18px; gap: 7px;
font-size: 11px; font-weight: 700; text-transform: uppercase;
letter-spacing: 0.1em; color: rgba(255,255,255,0.9); white-space: nowrap;
}
.ticker-track {
display: flex; gap: 64px;
animation: ticker 44s linear infinite;
padding-left: 100vw; white-space: nowrap;
font-size: 13px; font-weight: 500; color: rgba(255,255,255,0.92);
}
.ticker-track span::before { content: '●'; margin-right: 14px; opacity: 0.45; font-size: 8px; vertical-align: middle; }
.ticker-track span:first-child::before { display: none; }
@keyframes ticker { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } }
/* === HERO ESTÁTICO === */
.hero {
position: relative;
width: 100%;
overflow: hidden;
margin-bottom: 0;
line-height: 0;
}
.hero-banner {
width: 100%;
height: auto;
max-height: 540px;
object-fit: cover;
object-position: center top;
display: block;
}
.btn-primary {
display: inline-flex; align-items: center; gap: 8px;
padding: 11px 22px; border-radius: 10px;
background: var(--blue); color: #fff;
font-size: 14px; font-weight: 600;
transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
box-shadow: 0 0 26px var(--blue-gl);
}
.btn-primary:hover { background: var(--blue-2); transform: translateY(-2px); box-shadow: 0 6px 32px var(--blue-gl); }
.btn-secondary {
display: inline-flex; align-items: center; gap: 8px;
padding: 11px 18px; border-radius: 10px;
background: rgba(255,255,255,0.07); color: var(--text-2);
font-size: 14px; font-weight: 500; border: 1px solid var(--border);
transition: background 0.2s;
}
.btn-secondary:hover { background: rgba(255,255,255,0.12); color: var(--text); }
/* === STATS BAR === */
.stats-bar {
background: var(--bg-1);
border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
padding: 22px 0; margin-bottom: 48px;
}
.stats-bar .container { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; }
.stat-item { text-align: center; }
.stat-num {
font-family: var(--fh); font-size: 38px; font-weight: 900; line-height: 1;
background: linear-gradient(135deg, var(--blue-2), var(--gold));
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
background-clip: text;
}
.stat-label { font-size: 11px; color: var(--text-3); margin-top: 5px; letter-spacing: 0.07em; text-transform: uppercase; }
/* === SECTION HEADER === */
.section-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; }
.section-title {
font-family: var(--fh); font-weight: 900;
font-size: 26px; letter-spacing: -0.02em; color: var(--text);
display: flex; align-items: center; gap: 10px;
}
.section-title::before {
content: ''; display: block; width: 4px; height: 26px;
border-radius: 2px; background: var(--blue);
}
.section-more {
font-size: 13px; font-weight: 500; color: var(--blue-2);
display: flex; align-items: center; gap: 5px; transition: gap 0.2s;
}
.section-more:hover { gap: 9px; }
/* === CATEGORIES === */
.categories { margin-bottom: 40px; }
.categories .container { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cat-pill {
padding: 8px 16px; border-radius: 99px;
font-size: 13px; font-weight: 500;
background: var(--bg-2); color: var(--text-2);
border: 1px solid var(--border); transition: all 0.2s; cursor: pointer;
}
.cat-pill:hover { background: var(--blue-gl2); color: var(--blue-2); border-color: rgba(26,79,255,0.3); }
.cat-pill.active { background: var(--blue); color: #fff; border-color: var(--blue); box-shadow: 0 0 18px var(--blue-gl); }
/* === CARD === */
.card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--r-lg); overflow: hidden;
transition: border-color 0.25s, transform 0.25s, box-shadow 0.25s;
}
.card:hover { border-color: var(--border-h); transform: translateY(-3px); box-shadow: 0 14px 48px rgba(0,0,0,0.45); }
.card-img-wrap { overflow: hidden; }
.card-img { width: 100%; aspect-ratio: 16/10; object-fit: cover; transition: transform 0.55s ease; }
.card-img-placeholder { width: 100%; aspect-ratio: 16/10; background: linear-gradient(135deg, #002B5C 0%, #003f8a 60%, #1a56a0 100%); display: flex; align-items: center; justify-content: center; font-size: 2.5rem; opacity: 0.85; }
.card:hover .card-img { transform: scale(1.04); }
.card-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 10px; }
.card-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card-dot { width: 3px; height: 3px; border-radius: 50%; background: var(--text-3); }
.card-time { font-size: 12px; color: var(--text-3); }
.card-title {
font-family: var(--fh); font-weight: 800;
font-size: 20px; line-height: 1.12; letter-spacing: -0.01em; color: var(--text);
transition: color 0.2s;
}
.card:hover .card-title { color: var(--blue-2); }
.card-excerpt { font-size: 13.5px; color: var(--text-2); line-height: 1.62; }
.card-footer {
display: flex; align-items: center; justify-content: space-between;
padding-top: 12px; border-top: 1px solid var(--border); margin-top: auto;
}
.card-author { display: flex; align-items: center; gap: 8px; }
.card-avatar {
width: 28px; height: 28px; border-radius: 50%;
background: var(--blue-gl2); border: 1px solid rgba(59,111,255,0.25);
font-size: 10px; font-weight: 700; color: var(--blue-2);
display: flex; align-items: center; justify-content: center;
}
.card-author-name { font-size: 12px; color: var(--text-2); font-weight: 500; }
.card-stats { display: flex; align-items: center; gap: 12px; }
.card-stat { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--text-3); }
/* === NEWS GRID === */
.news-section { margin-bottom: 56px; }
.news-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); }
.card-featured {
grid-column: span 2;
display: grid; grid-template-columns: 1.35fr 1fr;
}
.card-featured .card-img { aspect-ratio: unset; height: 100%; min-height: 290px; }
.card-featured .card-img-placeholder { aspect-ratio: unset; height: 100%; min-height: 290px; font-size: 4rem; }
.card-featured .card-title { font-size: 27px; }
.card-featured .card-excerpt { font-size: 14.5px; }
/* === MATCHES === */
.matches-section { margin-bottom: 56px; }
.matches-scroll { display: flex; gap: var(--gap); overflow-x: auto; padding-bottom: 6px; scroll-snap-type: x mandatory; }
.matches-scroll::-webkit-scrollbar { height: 3px; }
.matches-scroll::-webkit-scrollbar-track { background: var(--bg-2); border-radius: 2px; }
.matches-scroll::-webkit-scrollbar-thumb { background: var(--border-h); border-radius: 2px; }
.match-card {
flex-shrink: 0; min-width: 280px; scroll-snap-align: start;
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--r-lg); padding: 20px 22px;
transition: border-color 0.25s, transform 0.25s;
}
.match-card:hover { border-color: rgba(59,111,255,0.25); transform: translateY(-2px); }
.match-card.featured { border-color: rgba(26,79,255,0.28); box-shadow: 0 0 28px var(--blue-gl2); }
.match-competition {
font-size: 11px; font-weight: 600; letter-spacing: 0.07em;
text-transform: uppercase; color: var(--text-3); margin-bottom: 16px;
}
.match-teams { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 16px; }
.match-team { display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 1; }
.match-team-logo {
width: 48px; height: 48px; border-radius: 50%;
background: var(--bg-2); border: 1px solid var(--border);
display: flex; align-items: center; justify-content: center; font-size: 22px;
}
.match-team-name { font-family: var(--fh); font-size: 15px; font-weight: 700; color: var(--text); text-align: center; }
.match-vs { font-family: var(--fh); font-size: 22px; font-weight: 900; color: var(--text-3); }
.match-time { background: var(--bg-2); border-radius: 10px; padding: 10px 14px; text-align: center; }
.match-date { font-size: 12px; color: var(--text-2); margin-bottom: 4px; }
.match-countdown { font-family: var(--fh); font-size: 22px; font-weight: 800; color: var(--blue-2); letter-spacing: 0.02em; }
/* === MAIN + SIDEBAR === */
.main-section { margin-bottom: 56px; }
.main-grid { display: grid; grid-template-columns: 1fr 340px; gap: 32px; align-items: start; }
.article-list { display: flex; flex-direction: column; gap: 14px; }
.article-item {
display: flex; gap: 16px; padding: 16px;
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--r); transition: border-color 0.2s, transform 0.2s;
}
.article-item:hover { border-color: var(--border-h); transform: translateX(4px); }
.article-thumb { flex-shrink: 0; width: 118px; height: 78px; border-radius: 10px; overflow: hidden; }
.article-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s; }
.article-item:hover .article-thumb img { transform: scale(1.07); }
.article-body { display: flex; flex-direction: column; gap: 6px; flex: 1; }
.article-title {
font-family: var(--fh); font-size: 18px; font-weight: 800;
line-height: 1.14; color: var(--text); transition: color 0.2s;
}
.article-item:hover .article-title { color: var(--blue-2); }
.article-excerpt { font-size: 13px; color: var(--text-2); line-height: 1.55; }
/* === SIDEBAR === */
.sidebar { display: flex; flex-direction: column; gap: 20px; }
.sidebar-widget { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.widget-header {
padding: 14px 18px; border-bottom: 1px solid var(--border);
display: flex; align-items: center; gap: 8px;
font-family: var(--fh); font-size: 17px; font-weight: 800; color: var(--text);
}
.widget-header svg { color: var(--blue-2); }
/* === STANDINGS WIDGET === */
.standings-header {
display: grid; grid-template-columns: 26px 1fr 22px 22px 22px 28px;
gap: 4px; padding: 6px 14px 7px;
font-size: 10px; font-weight: 700; text-transform: uppercase;
letter-spacing: 0.6px; color: var(--text-3);
border-bottom: 1px solid var(--border);
}
.standings-row {
display: grid; grid-template-columns: 26px 1fr 22px 22px 22px 28px;
align-items: center; gap: 4px;
padding: 6px 14px; transition: background 0.15s;
font-size: 12.5px;
}
.standings-row:hover { background: rgba(255,255,255,0.03); }
.standings-row.porto {
background: rgba(0,82,164,0.18);
border-left: 3px solid var(--blue-2);
padding-left: 11px;
}
.s-pos { color: var(--text-3); font-weight: 700; text-align: center; }
.s-pos.cl { color: #4ade80; }
.s-pos.el { color: #facc15; }
.s-pos.rel { color: #f87171; }
.s-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.s-name.porto-name { font-weight: 700; color: var(--blue-2); }
.s-num { text-align: center; color: var(--text-2); font-size: 11.5px; }
.s-pts { text-align: center; font-weight: 800; color: var(--text); }
.trending-list { padding: 6px 0; }
.trending-item {
display: flex; align-items: flex-start; gap: 12px;
padding: 10px 18px; transition: background 0.2s;
}
.trending-item:hover { background: rgba(255,255,255,0.025); }
.trending-num { font-family: var(--fh); font-size: 22px; font-weight: 900; color: var(--text-3); line-height: 1; flex-shrink: 0; width: 22px; }
.trending-num.top { color: var(--blue-2); }
.trending-title { font-size: 13.5px; font-weight: 500; color: var(--text); line-height: 1.4; transition: color 0.2s; }
.trending-item:hover .trending-title { color: var(--blue-2); }
.newsletter-widget { padding: 20px 18px; }
.newsletter-widget p { font-size: 13px; color: var(--text-2); margin: 8px 0 16px; line-height: 1.55; }
.input-field {
width: 100%; background: var(--bg-2); border: 1px solid var(--border);
border-radius: 10px; padding: 10px 14px;
color: var(--text); font-size: 14px; font-family: var(--fb);
outline: none; margin-bottom: 10px; transition: border-color 0.2s;
}
.input-field:focus { border-color: var(--blue); }
.input-field::placeholder { color: var(--text-3); }
.btn-subscribe {
width: 100%; padding: 11px;
background: var(--blue); color: #fff;
border-radius: 10px; font-size: 14px; font-weight: 600;
font-family: var(--fb); cursor: pointer;
transition: background 0.2s; border: none;
}
.btn-subscribe:hover { background: var(--blue-2); }
.social-links { padding: 14px 18px; display: flex; flex-direction: column; gap: 10px; }
.social-link {
display: flex; align-items: center; gap: 12px; padding: 10px 12px;
background: var(--bg-2); border-radius: 10px; border: 1px solid var(--border);
transition: border-color 0.2s;
}
.social-link:hover { border-color: rgba(59,111,255,0.3); }
.social-link-info { display: flex; flex-direction: column; }
.social-link-name { font-size: 13px; font-weight: 600; color: var(--text); }
.social-link-count { font-size: 12px; color: var(--text-3); }
/* === GLOW DIVIDER === */
.glow-divider {
height: 1px;
background: linear-gradient(90deg, transparent, var(--blue-gl), var(--gold-gl), transparent);
margin: 48px 0;
}
/* === FOOTER === */
.footer { background: var(--bg-1); border-top: 1px solid var(--border); padding: 36px 0 20px; }
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr auto; gap: 32px; margin-bottom: 24px; align-items: start; }
.footer-brand p { font-size: 13px; color: var(--text-2); line-height: 1.6; max-width: 260px; margin: 10px 0 14px; }
.footer-socials { display: flex; gap: 8px; }
.footer-socials a {
width: 32px; height: 32px; border-radius: 8px;
background: var(--bg-2); border: 1px solid var(--border);
display: flex; align-items: center; justify-content: center;
color: var(--text-2); transition: all 0.2s;
}
.footer-socials a:hover { background: var(--blue-gl2); border-color: rgba(59,111,255,0.3); color: var(--blue-2); transform: translateY(-2px); }
.footer-col h4 { font-family: var(--fh); font-size: 15px; font-weight: 800; color: var(--text); margin-bottom: 12px; letter-spacing: -0.01em; }
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.footer-col ul a { font-size: 13px; color: var(--text-2); transition: color 0.2s; }
.footer-col ul a:hover { color: var(--blue-2); }
.footer-classif {
padding: 14px 16px; background: var(--blue-gl2);
border: 1px solid rgba(59,111,255,0.2); border-radius: 10px;
min-width: 160px;
}
.footer-classif-label { font-size: 11px; color: var(--blue-2); font-weight: 600; margin-bottom: 3px; }
.footer-classif-name { font-family: var(--fh); font-size: 17px; font-weight: 900; color: var(--text); }
.footer-classif-info { font-size: 11px; color: var(--text-2); margin-top: 2px; }
.footer-bottom {
padding-top: 16px; border-top: 1px solid var(--border);
display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px;
}
.footer-bottom p { font-size: 12px; color: var(--text-3); }
.footer-bottom .heart { display: flex; align-items: center; gap: 5px; }
/* === MOBILE MENU === */
.mobile-menu {
position: fixed; inset: 0; z-index: 2000;
background: rgba(7,11,20,0.97); backdrop-filter: blur(28px);
display: flex; flex-direction: column; padding: 24px; gap: 6px;
transform: translateX(100%);
transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
.mobile-menu.open { transform: translateX(0); }
.mobile-menu-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.mobile-menu a {
padding: 14px 16px; border-radius: 12px;
font-size: 24px; font-family: var(--fh); font-weight: 700; color: var(--text-2); transition: all 0.2s;
}
.mobile-menu a:hover, .mobile-menu a.active { background: var(--blue-gl2); color: var(--blue-2); }
/* === SCROLL ANIMATIONS === */
.fade-up { opacity: 0; transform: translateY(22px); transition: opacity 0.55s ease, transform 0.55s ease; }
.fade-up.visible { opacity: 1; transform: translateY(0); }
/* === SPIN === */
@keyframes spin { to { transform: rotate(360deg); } }
/* === RESPONSIVE === */
@media (max-width: 1100px) {
.news-grid { grid-template-columns: 1fr 1fr; }
.card-featured { grid-column: span 2; }
.main-grid { grid-template-columns: 1fr; }
.footer-grid { grid-template-columns: 1fr 1fr; }
.footer-classif { grid-column: span 2; }
.stats-bar .container { grid-template-columns: repeat(4, 1fr); }
}
@media (max-width: 768px) {
.nav-links { display: none; }
.btn-live span { display: none; }
.btn-hamburger { display: flex; }
.hero-title { font-size: 28px; }
.hero-excerpt { display: none; }
.news-grid { grid-template-columns: 1fr; }
.card-featured { grid-column: span 1; grid-template-columns: 1fr; }
.card-featured .card-img { min-height: 200px; height: auto; aspect-ratio: 16/9; }
.footer-grid { grid-template-columns: 1fr; }
.stats-bar .container { grid-template-columns: repeat(2, 1fr); }
.topbar { display: none; }
}
@media (max-width: 480px) {
.stats-bar .container { grid-template-columns: repeat(2, 1fr); }
.article-thumb { width: 96px; height: 66px; }
}
/* === PAGE ROUTING === */
.page-content { display: none; }
.page-content.active { display: block; }
/* === INNER PAGE HERO === */
.page-hero {
background: linear-gradient(160deg, var(--bg-1) 0%, var(--bg-2) 100%);
border-bottom: 1px solid var(--border);
padding: 52px 0 48px; margin-bottom: 40px;
}
.page-hero .container { text-align: center; }
.page-hero-icon { font-size: 46px; margin-bottom: 14px; line-height: 1; }
.page-hero-title {
font-family: var(--fh); font-size: 46px; font-weight: 900;
letter-spacing: -0.02em; color: var(--text); line-height: 1.08; margin-bottom: 12px;
}
.page-hero-title span { color: var(--blue-2); }
.page-hero-sub { font-size: 15px; color: var(--text-2); max-width: 500px; margin: 0 auto; line-height: 1.65; }
/* === MODALIDADES HERO === */
.modalidades-hero {
background: linear-gradient(160deg, #030b1a 0%, #071020 40%, #0a1630 100%);
border-bottom: 2px solid rgba(26,79,255,0.35);
position: relative; overflow: hidden;
}
.modalidades-hero::before {
content: ''; position: absolute; inset: 0;
background:
radial-gradient(ellipse 80% 55% at 50% -10%, rgba(26,79,255,0.22) 0%, transparent 65%),
radial-gradient(ellipse 40% 40% at 15% 100%, rgba(26,79,255,0.08) 0%, transparent 60%),
radial-gradient(ellipse 40% 40% at 85% 100%, rgba(26,79,255,0.08) 0%, transparent 60%);
pointer-events: none;
}
.modalidades-hero::after {
content: ''; position: absolute; inset: 0;
background-image: radial-gradient(rgba(26,79,255,0.06) 1px, transparent 1px);
background-size: 28px 28px;
pointer-events: none; opacity: 0.6;
}
.mod-hero-icons {
display: flex; align-items: center; justify-content: center;
gap: 10px; flex-wrap: wrap; margin-bottom: 24px;
}
.mod-hero-icon-pill {
width: 44px; height: 44px; border-radius: 12px;
background: rgba(26,79,255,0.1); border: 1px solid rgba(26,79,255,0.22);
display: flex; align-items: center; justify-content: center;
color: var(--blue-2); font-size: 18px;
transition: background 0.2s, transform 0.2s;
}
.mod-hero-icon-pill:hover { background: rgba(26,79,255,0.2); transform: translateY(-2px); }
.mod-hero-stats {
display: flex; align-items: center; justify-content: center;
gap: 28px; margin-top: 28px; flex-wrap: wrap;
}
.mod-hero-stat { text-align: center; }
.mod-hero-stat-val { display: block; font-family: var(--fh); font-size: 28px; font-weight: 900; color: var(--blue-2); line-height: 1; }
.mod-hero-stat-lbl { display: block; font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.08em; margin-top: 4px; }
.mod-hero-stat-div { width: 1px; height: 32px; background: var(--border); }
/* === APOSTA HERO === */
.aposta-hero {
background: linear-gradient(160deg, #0e0005 0%, #1a0009 40%, #160007 100%);
border-bottom: 2px solid var(--bc);
position: relative; overflow: hidden;
}
.aposta-hero::before {
content: ''; position: absolute; inset: 0;
background: radial-gradient(ellipse 80% 70% at 50% 0%, rgba(228,0,43,0.14) 0%, transparent 70%);
pointer-events: none;
}
.aposta-hero .page-hero-title span { color: var(--bc); }
.aposta-hero-top {
display: flex; align-items: center; justify-content: center;
gap: 12px; margin-bottom: 16px; flex-wrap: wrap;
}
.aposta-hero-label {
display: inline-flex; align-items: center; gap: 7px;
background: rgba(228,0,43,0.12); border: 1px solid rgba(228,0,43,0.25);
color: var(--bc); font-size: 11px; font-weight: 700;
letter-spacing: 0.08em; text-transform: uppercase;
padding: 5px 12px; border-radius: 99px;
}
@keyframes betclic-pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(228,0,43,0.7), 0 0 12px rgba(228,0,43,0.4); background: var(--bc); }
50% { box-shadow: 0 0 0 6px rgba(228,0,43,0), 0 0 24px rgba(228,0,43,0.6); background: #ff1a3c; }
}
.aposta-betclic-wordmark {
font-family: var(--fh); font-size: 22px; font-weight: 900;
color: #fff; letter-spacing: 0.05em;
background: var(--bc); padding: 4px 14px; border-radius: 8px;
line-height: 1.3; animation: betclic-pulse 1.8s ease-in-out infinite;
cursor: default;
}
.aposta-betclic-wordmark span { color: rgba(255,255,255,0.85); }
.aposta-hero-banner {
display: block; margin: 24px auto 0;
max-width: 680px; width: 100%;
border-radius: 12px; overflow: hidden;
box-shadow: 0 0 32px rgba(228,0,43,0.25);
transition: transform 0.2s, box-shadow 0.2s;
}
.aposta-hero-banner:hover { transform: translateY(-2px); box-shadow: 0 0 48px rgba(228,0,43,0.38); }
.aposta-hero-banner img { width: 100%; display: block; }
.aposta-hero-disclaimer { font-size: 10px; color: var(--text-3); margin-top: 10px; }
.aposta-hero-disclaimer a { color: var(--text-3); text-decoration: underline; }
/* === CAPAS HERO === */
.capas-hero {
background: linear-gradient(160deg, #0d0a02 0%, #16120a 40%, #1a1508 100%);
border-bottom: 1px solid rgba(232,200,64,0.15);
position: relative; overflow: hidden;
}
.capas-hero::before {
content: ''; position: absolute; inset: 0;
background: radial-gradient(ellipse 70% 60% at 50% 0%, rgba(232,200,64,0.07) 0%, transparent 70%);
pointer-events: none;
}
.capas-hero-label {
display: inline-flex; align-items: center; gap: 8px;
background: rgba(232,200,64,0.1); border: 1px solid rgba(232,200,64,0.22);
color: #e8c840; font-size: 12px; font-weight: 700;
letter-spacing: 0.08em; text-transform: uppercase;
padding: 6px 14px; border-radius: 99px; margin-bottom: 16px;
}
.capas-hero .page-hero-title span { color: #e8c840; }
/* === TRANSFER HERO === */
.transfer-hero {
background: linear-gradient(160deg, #050d1f 0%, #0a1205 40%, #081a0a 100%);
border-bottom: 1px solid rgba(34,212,126,0.15);
position: relative; overflow: hidden;
}
.transfer-hero::before {
content: ''; position: absolute; inset: 0;
background: radial-gradient(ellipse 70% 60% at 50% 0%, rgba(34,212,126,0.08) 0%, transparent 70%);
pointer-events: none;
}
.transfer-hero-label {
display: inline-flex; align-items: center; gap: 8px;
background: rgba(34,212,126,0.1); border: 1px solid rgba(34,212,126,0.22);
color: var(--green); font-size: 12px; font-weight: 700;
letter-spacing: 0.08em; text-transform: uppercase;
padding: 6px 14px; border-radius: 99px; margin-bottom: 16px;
}
.transfer-hero .page-hero-title span { color: var(--green); }
/* === MODALITIES === */
.modalities-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 20px; padding-bottom: 60px;
}
.modality-card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--r-lg); padding: 24px 22px;
display: flex; flex-direction: column; gap: 10px;
transition: border-color 0.25s, transform 0.25s, box-shadow 0.25s;
}
.modality-card:hover { border-color: var(--border-h); transform: translateY(-3px); box-shadow: 0 14px 48px rgba(0,0,0,.4); }
.mod-icon {
width: 48px; height: 48px;
display: flex; align-items: center; justify-content: center;
background: var(--blue-gl2); border: 1px solid rgba(26,79,255,0.18);
border-radius: 12px; color: var(--blue-2); margin-bottom: 4px;
}
.mod-icon svg { width: 26px; height: 26px; stroke-width: 1.7; }
.mod-icon i { font-size: 22px; }
.mod-name { font-family: var(--fh); font-size: 22px; font-weight: 800; color: var(--text); line-height: 1.1; }
.mod-desc { font-size: 13px; color: var(--text-2); line-height: 1.62; flex: 1; }
.mod-link {
font-size: 13px; font-weight: 600; color: var(--blue-2);
display: inline-flex; align-items: center; gap: 5px;
transition: gap 0.2s; margin-top: 4px; cursor: pointer;
}
.mod-link:hover { gap: 9px; }
.mod-news { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.mod-news:empty { display: none; }
.mod-news-item { display: flex; flex-direction: column; gap: 1px; text-decoration: none; padding: 5px 7px; border-radius: 6px; transition: background 0.2s; }
.mod-news-item:hover { background: rgba(255,255,255,.05); }
.mod-news-title { font-size: 11.5px; color: var(--text); line-height: 1.4; font-weight: 500; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.mod-news-time { font-size: 10px; color: var(--text-3); }
/* === TRANSFERS === */
.transfers-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; padding-bottom: 60px; }
@media (max-width: 900px) { .transfers-cols { grid-template-columns: 1fr; } }
.transfers-col-title {
font-family: var(--fh); font-size: 18px; font-weight: 800;
padding-bottom: 14px; margin-bottom: 16px;
border-bottom: 2px solid; display: flex; align-items: center; gap: 8px;
}
.tc-arrivals { border-color: var(--green); color: var(--green); }
.tc-departures { border-color: var(--red); color: var(--red); }
.tc-rumours { border-color: var(--gold); color: var(--gold); }
.transfer-card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--r); padding: 13px 15px;
display: flex; align-items: center; gap: 11px; margin-bottom: 9px;
transition: border-color 0.2s;
}
.transfer-card:hover { border-color: var(--border-h); }
.transfer-avatar {
width: 44px; height: 44px; border-radius: 50%;
background: linear-gradient(135deg, #0038CC, var(--blue));
display: flex; align-items: center; justify-content: center;
font-size: 13px; font-weight: 800; color: rgba(255,255,255,0.75);
font-family: var(--fh); flex-shrink: 0;
overflow: hidden; border: 1px solid var(--border);
}
.transfer-avatar img {
width: 100%; height: 100%; object-fit: cover; object-position: top center;
}
.transfer-info { flex: 1; min-width: 0; }
.transfer-name { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.transfer-pos { font-size: 11px; color: var(--text-3); }
.transfer-club { font-size: 12px; color: var(--text-2); margin-top: 2px; }
.transfer-fee { font-size: 11px; font-weight: 700; color: var(--gold); white-space: nowrap; }
.transfer-window {
background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--r);
padding: 12px 16px; margin-bottom: 20px; font-size: 12px; color: var(--text-3);
display: flex; align-items: center; gap: 7px;
}
/* === LIVE STREAMS === */
.streams-intro { max-width: 640px; margin: 0 auto 36px; text-align: center; font-size: 14px; color: var(--text-2); line-height: 1.65; }
.streams-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px; margin-bottom: 36px; }
.stream-card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--r-lg); padding: 22px; text-align: center;
display: flex; flex-direction: column; align-items: center; gap: 9px;
transition: border-color 0.25s, transform 0.25s;
}
.stream-card:hover { border-color: var(--border-h); transform: translateY(-3px); }
.stream-icon { font-size: 34px; line-height: 1; }
.stream-name { font-family: var(--fh); font-size: 19px; font-weight: 800; color: var(--text); }
.stream-desc { font-size: 12px; color: var(--text-2); line-height: 1.55; }
.stream-badge-pill { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 99px; }
.sbp-paid { background: rgba(240,176,48,0.1); color: var(--gold); border: 1px solid rgba(240,176,48,0.25); }
.sbp-free { background: rgba(34,212,126,0.1); color: var(--green); border: 1px solid rgba(34,212,126,0.22); }
.stream-tip {
background: var(--bg-1); border: 1px solid var(--border); border-radius: var(--r);
padding: 16px 20px; font-size: 13px; color: var(--text-2); line-height: 1.65;
margin-bottom: 48px;
}
.stream-tip strong { color: var(--text); }
.live-sched-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; padding-bottom: 60px; }
.live-match-card {
background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 18px 20px;
display: flex; align-items: center; gap: 16px;
}
.live-match-date { font-size: 12px; color: var(--text-3); margin-bottom: 4px; }
.live-match-name { font-size: 14px; font-weight: 600; color: var(--text); }
.live-match-comp { font-size: 12px; color: var(--text-2); margin-top: 2px; }
.live-match-where { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; margin-left: auto; }
/* === NEWSPAPERS === */
.newspapers-intro { max-width: 600px; margin: 0 auto 32px; text-align: center; font-size: 14px; color: var(--text-2); line-height: 1.65; }
.newspapers-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 320px)); gap: 22px; padding-bottom: 60px; justify-content: center; }
.newspaper-card {
background: var(--bg-card); border: 1px solid var(--border);
border-radius: var(--r-lg); overflow: hidden;
transition: border-color 0.25s, transform 0.25s, box-shadow 0.25s;
display: flex; flex-direction: column;
}
.newspaper-card:hover { border-color: var(--border-h); transform: translateY(-3px); box-shadow: 0 14px 48px rgba(0,0,0,.4); }
.newspaper-header {
padding: 18px 20px 14px; display: flex; align-items: center; gap: 13px;
border-bottom: 1px solid var(--border);
}
.newspaper-logo-box {
width: 48px; height: 48px; border-radius: 10px; flex-shrink: 0;
display: flex; align-items: center; justify-content: center; font-size: 22px;
}
.newspaper-name { font-family: var(--fh); font-size: 21px; font-weight: 900; color: var(--text); }
.newspaper-tagline { font-size: 11px; color: var(--text-3); margin-top: 1px; }
.newspaper-cover-area {
flex: 1; min-height: 220px; margin: 14px;
background: linear-gradient(160deg, #0A1428 0%, #0E1B30 100%);
border-radius: var(--r); border: 1px solid var(--border);
display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px;
overflow: hidden; position: relative;
}
.newspaper-cover-area.has-cover { padding: 0; background: #000; border-color: transparent; }
.newspaper-cover-area img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: var(--r); }
.newspaper-cover-emoji { font-size: 40px; opacity: 0.3; }
.newspaper-cover-lbl { font-size: 11px; color: var(--text-3); }
.newspaper-footer-bar {
padding: 14px 18px; display: flex; align-items: center; justify-content: space-between;
border-top: 1px solid var(--border);
}
.newspaper-date { font-size: 11px; color: var(--text-3); }
/* === APOSTA DO DIA === */
.bet-disclaimer {
background: rgba(240,176,48,0.05); border: 1px solid rgba(240,176,48,0.18);
border-radius: var(--r); padding: 13px 17px;
font-size: 12px; color: var(--text-2); line-height: 1.62;
margin-bottom: 28px; display: flex; gap: 10px; align-items: flex-start;
}
.bet-disclaimer-icon { font-size: 16px; flex-shrink: 0; margin-top: 2px; }
.bet-main-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 22px; margin-bottom: 48px; }
@media (max-width: 768px) { .bet-main-grid { grid-template-columns: 1fr; } }
.bet-match-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.bet-match-header {
background: linear-gradient(135deg, #071528, #0a1f3d);
padding: 16px 22px; border-bottom: 1px solid var(--border);
display: flex; align-items: center; justify-content: space-between;
}
.bet-comp-label { font-size: 11px; color: var(--text-3); letter-spacing: 0.04em; text-transform: uppercase; }
.bet-comp-name { font-size: 14px; font-weight: 600; color: var(--text-2); margin-top: 2px; }
.bet-match-date { font-size: 13px; font-weight: 600; color: var(--blue-2); }
.bet-match-body { padding: 22px 22px 18px; }
.bet-teams { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 22px; }
.bet-team { text-align: center; flex: 1; }
.bet-team-logo { font-size: 40px; margin-bottom: 8px; line-height: 1; height: 70px; display: flex; align-items: center; justify-content: center; }
.bet-team-name { font-family: var(--fh); font-size: 17px; font-weight: 800; color: var(--text); }
.bet-vs { font-family: var(--fh); font-size: 24px; font-weight: 900; color: var(--text-3); flex-shrink: 0; }
.bet-pick {
background: rgba(228,0,43,0.08); border: 1px solid rgba(228,0,43,0.25);
border-radius: var(--r); padding: 16px 18px; margin-bottom: 18px;
display: flex; align-items: center; gap: 14px;
}
.bet-pick-icon { font-size: 28px; flex-shrink: 0; }
.bet-pick-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-3); margin-bottom: 4px; }
.bet-pick-value { font-family: var(--fh); font-size: 22px; font-weight: 900; color: var(--bc); line-height: 1.1; }
.bet-pick-conf { font-size: 12px; color: var(--text-2); margin-top: 3px; }
.bet-analysis { font-size: 13.5px; color: var(--text-2); line-height: 1.68; }
/* ODDS */
.odds-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.odds-card-header { padding: 16px 18px; border-bottom: 1px solid var(--border); }
.odds-card-title { font-family: var(--fh); font-size: 17px; font-weight: 800; color: var(--text); }
.odds-pick-sum { font-size: 12px; color: var(--text-3); margin-top: 2px; }
.odds-row { display: flex; align-items: center; justify-content: space-between; padding: 13px 18px; border-bottom: 1px solid var(--border); }
.odds-row:last-child { border-bottom: 0; }
.odds-bookmaker { font-size: 13px; color: var(--text-2); font-weight: 500; }
.odds-val { font-family: var(--fh); font-size: 22px; font-weight: 900; color: var(--gold); }
/* Betclic featured row */
.odds-row-betclic {
display: flex; align-items: center; justify-content: space-between;
padding: 14px 18px; border-bottom: 1px solid rgba(228,0,43,0.2);
background: linear-gradient(90deg, rgba(228,0,43,0.12), rgba(228,0,43,0.06));
border-left: 3px solid var(--bc);
text-decoration: none; color: inherit; cursor: pointer;
transition: background 0.18s;
}
.odds-row-betclic:hover { background: linear-gradient(90deg, rgba(228,0,43,0.22), rgba(228,0,43,0.10)); }
.odds-row-betclic .odds-bookmaker { color: var(--bc); font-weight: 700; font-size: 14px; }
.odds-row-betclic .odds-val { color: var(--bc); font-size: 26px; }
.odds-betclic-badge { font-size: 9px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; background: var(--bc); color: #fff; padding: 2px 7px; border-radius: 99px; margin-left: 7px; vertical-align: middle; }
.odds-row-link { cursor: pointer; transition: background 0.18s; border-radius: 6px; text-decoration: none; color: inherit; display: flex; align-items: center; justify-content: space-between; padding: 13px 18px; border-bottom: 1px solid var(--border); }
.odds-row-link:hover { background: rgba(228,0,43,0.06); }
.odds-row-link .odds-right { display: flex; align-items: center; }
.odds-live-badge { display: flex; flex-direction: column; align-items: flex-end; margin-left: 10px; gap: 1px; min-width: 54px; }
.odds-live-up { font-size: 11px; font-weight: 700; color: #4ade80; }
.odds-live-down { font-size: 11px; font-weight: 700; color: #f87171; }
.odds-live-same { font-size: 11px; font-weight: 700; color: var(--text-3); }
.odds-live-time { font-size: 9px; color: var(--text-3); letter-spacing: 0.04em; }
.odds-hl .odds-val { color: var(--green); }
.odds-hl { background: rgba(34,212,126,0.04); }
/* Betclic CTA button */
.betclic-cta-btn {
display: flex; align-items: center; justify-content: center; gap: 10px;
background: var(--bc); color: #fff;
font-family: var(--fh); font-size: 18px; font-weight: 900;
letter-spacing: 0.04em; text-transform: uppercase;
padding: 16px 24px; border-radius: 0 0 var(--r-lg) var(--r-lg);
text-decoration: none; transition: background 0.2s, transform 0.15s;
border-top: 1px solid rgba(255,255,255,0.1);
}
.betclic-cta-btn:hover { background: var(--bc-2); transform: translateY(-1px); }
.betclic-cta-btn i { font-size: 16px; }
/* Stats */
.bet-stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 18px; }
.bet-stat { background: var(--bg-2); border: 1px solid var(--border); border-radius: var(--r); padding: 14px; text-align: center; }
.bet-stat-val { font-family: var(--fh); font-size: 28px; font-weight: 900; color: var(--bc); }
.bet-stat-lbl { font-size: 11px; color: var(--text-3); margin-top: 3px; }
/* Histórico */
.bet-past-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; margin-top: 20px; padding-bottom: 60px; }
.bet-past-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r); padding: 16px; transition: border-color 0.2s; }
.bet-past-card:hover { border-color: var(--border-h); }
.bet-past-match { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 6px; }
.bet-past-pick { font-size: 12px; color: var(--text-2); }
.bet-past-result { font-size: 13px; font-weight: 700; margin-top: 10px; display: flex; align-items: center; gap: 6px; padding-top: 10px; border-top: 1px solid var(--border); }
.res-win { color: var(--green); }
.res-loss { color: var(--red); }
.res-void { color: var(--text-3); }
</style>
<!-- Google AdSense -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2185320483550230" crossorigin="anonymous"></script>
</head>
<body>
<!-- MOBILE MENU -->
<div class="mobile-menu" id="mobileMenu">
<div class="mobile-menu-header">
<div class="nav-logo">
<div class="nav-logo-icon"><img src="/assets/logo-B3SSC6e3.jpg" alt="Porto Até Morrer"></div>
<div>
<div class="nav-logo-text">Porto <span>Até Morrer</span></div>
</div>
</div>
<button class="btn-icon" onclick="toggleMenu()">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<a href="javascript:void(0)" data-page="futebol" class="active">⚽ Futebol</a>
<a href="javascript:void(0)" data-page="modalidades">🏅 Modalidades</a>
<a href="javascript:void(0)" data-page="transferencias">💰 Transferências</a>
<a href="javascript:void(0)" data-page="capas-jornais">📰 Capas Jornais Desportivos</a>
<a href="javascript:void(0)" data-page="aposta-dia">🎰 Aposta do Dia</a>
<a href="#">🔒 Política de Privacidade</a>
</div>
<!-- TOP BAR -->
<div class="topbar">
<div class="container">
<div class="topbar-left">
<div class="topbar-socials">
<a href="https://www.facebook.com/FCPATEAMORTE/" target="_blank" rel="noopener" aria-label="Facebook">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"/></svg>
</a>
<a href="https://www.instagram.com/portoatemorrer1893?igsh=ZGY2ZWdlbDdnNGcy" target="_blank" rel="noopener" aria-label="Instagram">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="2" y="2" width="20" height="20" rx="5"/><path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg>
</a>
</div>
<span class="topbar-date" id="topbarDate"></span>
</div>
<div class="topbar-right">
<span class="badge badge-blue">
<span class="live-dot" style="background:var(--blue-2)"></span>
PORTO NA FRENTE · Liga PT 1.º lugar
</span>
<a href="#" class="btn-live">
<span class="live-dot"></span>
<span>Direto</span>
</a>
</div>
</div>
</div>
<!-- NAVBAR -->
<nav class="navbar" id="navbar">
<div class="container">
<a href="javascript:void(0)" data-page="futebol" class="nav-logo">
<div class="nav-logo-icon"><img src="/assets/logo-B3SSC6e3.jpg" alt="Porto Até Morrer"></div>
<div>
<div class="nav-logo-text">Porto <span>Até Morrer</span></div>
<div class="nav-logo-sub">A Voz do Dragão</div>
</div>
</a>
<ul class="nav-links">
<li><a href="javascript:void(0)" data-page="futebol" class="active">Futebol</a></li>
<li><a href="javascript:void(0)" data-page="modalidades">Modalidades</a></li>
<li><a href="javascript:void(0)" data-page="transferencias">Transferências</a></li>
<li><a href="javascript:void(0)" data-page="capas-jornais">Capas Jornais</a></li>
<li><a href="javascript:void(0)" data-page="aposta-dia">Aposta do Dia</a></li>
</ul>
<div class="nav-actions">
<button class="btn-hamburger" onclick="toggleMenu()" aria-label="Abrir menu">
<span></span><span></span><span></span>
</button>
</div>
</div>
</nav>
<div id="page-futebol" class="page-content active">
<!-- HERO ESTÁTICO -->
<section class="hero">
<img src="/assets/banner-hero-Cj7xgu-3.png" alt="Porto Até Morrer" class="hero-banner" loading="eager">
</section>
<!-- STATS BAR -->
<div class="stats-bar">
<div class="container">
<div class="stat-item">
<div class="stat-num" id="statNum1">—</div>
<div class="stat-label" id="statLbl1">Pontos Liga PT</div>
</div>
<div class="stat-item">
<div class="stat-num" id="statNum2">—</div>
<div class="stat-label" id="statLbl2">Posição</div>
</div>
<div class="stat-item">
<div class="stat-num" id="statNum3">—</div>
<div class="stat-label" id="statLbl3">Golos Marcados</div>
</div>
<div class="stat-item">
<div class="stat-num" id="statNum4">—</div>
<div class="stat-label" id="statLbl4">Jogos na Liga</div>
</div>
</div>
</div>
<!-- MATCHES -->
<section class="matches-section">
<div class="container">
<div class="section-header">
<h2 class="section-title">Próximos Jogos</h2>
<a href="#" onclick="navTo('calendario');return false;" class="section-more">
Calendário completo
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</a>
</div>
<div id="matchesScroll" class="matches-scroll">
<div style="display:flex;align-items:center;justify-content:center;min-width:100%;padding:40px 0;gap:10px;color:var(--text-2)">
<span class="spinner" style="width:18px;height:18px;border:2px solid var(--border-h);border-top-color:var(--blue-2);border-radius:50%;animation:spin 0.7s linear infinite;display:inline-block"></span>
A carregar jogos…
</div>
</div>
</div>
</section>
<!-- MAIN + SIDEBAR -->
<section class="main-section">
<div class="container">
<div class="main-grid">
<div>
<div class="section-header">
<h2 class="section-title">Últimas Notícias</h2>
<a href="https://www.fcporto.pt/pt/noticias" target="_blank" rel="noopener noreferrer" class="section-more">
Ver mais
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</a>
</div>
<div class="article-list" id="articleList">
<div style="text-align:center;padding:40px 20px;color:var(--text-2);font-size:13px">A carregar…</div>
</div>
</div>
<!-- SIDEBAR -->
<aside class="sidebar">
<div class="sidebar-widget">
<div class="widget-header">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></svg>
Classificação — Liga Portugal
</div>
<div id="standingsTable">
<div style="padding:14px 18px;color:var(--text-3);font-size:13px">A carregar…</div>
</div>
</div>
</aside>
</div>
</div>
</section>
</div><!-- /page-futebol -->
<!-- ═══════════════════════════════════════════════════════════════
PAGE: MODALIDADES
═══════════════════════════════════════════════════════════════ -->
<div id="page-modalidades" class="page-content">
<div class="page-hero modalidades-hero" style="padding:60px 0 52px">
<div class="container" style="text-align:center;position:relative;z-index:1">
<h1 class="page-hero-title">Modalidades <span>FC Porto</span></h1>
<p class="page-hero-sub" style="max-width:480px;margin:0 auto">Muito mais do que futebol. O FC Porto é uma das maiores potências desportivas de Portugal em múltiplas modalidades.</p>
<div class="mod-hero-stats" style="margin-top:36px">
<div class="mod-hero-stat">
<span class="mod-hero-stat-val" style="font-size:36px">10</span>
<span class="mod-hero-stat-lbl">Modalidades</span>
</div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat">
<span class="mod-hero-stat-val" style="font-size:36px;color:var(--gold)">+100</span>
<span class="mod-hero-stat-lbl">Títulos Nacionais</span>
</div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat">
<span class="mod-hero-stat-val" style="font-size:36px;color:var(--green)">1893</span>
<span class="mod-hero-stat-lbl">Fundação</span>
</div>
</div>
</div>
</div>
<section style="padding: 0 0 0">
<div class="container">
<div class="section-header">
<h2 class="section-title">Todas as Modalidades</h2>
<a href="https://www.fcporto.pt/pt/clube/modalidades" target="_blank" rel="noopener" class="section-more">
Site oficial
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</a>
</div>
<div class="modalities-grid">
<div class="modality-card fade-up" data-news-keyword="*">
<div class="mod-icon"><i class="fa-solid fa-futbol"></i></div>
<div class="mod-name">Futebol Masculino</div>
<div><span class="badge badge-blue"><span class="live-dot" style="background:var(--blue-2)"></span>Liga PT · 1.º Lugar</span></div>
<p class="mod-desc">A equipa principal compete na Liga Portugal Betclic, na UEFA Europa League e na Taça de Portugal. Treinador: Vítor Bruno. Estádio: Dragão (50.033 lug).</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up" data-news-cat-id="24">
<div class="mod-icon"><i class="fa-solid fa-futbol"></i></div>
<div class="mod-name">Futebol Feminino</div>
<div><span class="badge badge-green">Liga BPI</span></div>
<p class="mod-desc">A equipa feminina compete na Liga BPI — o principal campeonato feminino em Portugal — e nas provas europeias da UEFA. Campeãs nacionais em 2022 e 2023.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/futebol/feminino" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up" data-news-cat-id="4">
<div class="mod-icon"><i class="fa-solid fa-basketball"></i></div>
<div class="mod-name">Basquetebol</div>
<div><span class="badge badge-gold">Liga Betclic</span></div>
<p class="mod-desc">Histórico clube do basquetebol português. O FC Porto Basquetebol disputa títulos nacionais e provas europeias da FIBA. Vários campeões nacionais no currículo.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/modalidades/basquetebol/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up" data-news-cat-id="3">
<div class="mod-icon"><i class="fa-solid fa-volleyball"></i></div>
<div class="mod-name">Andebol</div>
<div><span class="badge badge-blue">Divisão de Elite</span></div>
<p class="mod-desc">A equipa de andebol compete na Divisão de Elite, o principal escalão nacional. Um dos clubes mais titulados de Portugal nesta modalidade, com participações europeias frequentes.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/modalidades/andebol/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up" data-news-cat-id="8">
<div class="mod-icon"><i class="fa-solid fa-hockey-puck"></i></div>
<div class="mod-name">Hóquei em Patins</div>
<div><span class="badge badge-red">OK Liga</span></div>
<p class="mod-desc">Uma das modalidades mais gloriosas do clube. O FC Porto é campeão europeu e um dos clubes mais titulados do mundo. Desporto radicado na cultura portista desde os anos 30.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/modalidades/hoquei/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up" data-news-cat-id="12">
<div class="mod-icon"><i class="fa-solid fa-person-swimming"></i></div>
<div class="mod-name">Natação</div>
<div><span class="badge badge-dark">Alto Rendimento</span></div>
<p class="mod-desc">Uma das melhores secções de natação do país. Nadadores portistas representam Portugal em Europeus e Mundiais, com vários recordes nacionais conquistados.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/modalidades/natacao/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up">
<div class="mod-icon"><i class="fa-solid fa-person-running"></i></div>
<div class="mod-name">Atletismo</div>
<div><span class="badge badge-dark">Federação</span></div>
<p class="mod-desc">Secção histórica que formou vários atletas de alto rendimento e representantes da selecção nacional portuguesa, com palmarés nas provas de pista e fundo.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/modalidades/atletismo/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up" data-news-cat-id="5">
<div class="mod-icon"><i class="fa-solid fa-hand-fist"></i></div>
<div class="mod-name">Boxe</div>
<div><span class="badge badge-dark">Federação</span></div>
<p class="mod-desc">O boxe é uma das secções mais antigas do FC Porto. Longa tradição desportiva com vários campeões nacionais e internacionais formados na academia portista.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/modalidades/boxe/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up" data-news-cat-id="14">
<div class="mod-icon"><i class="fa-solid fa-dragon"></i></div>
<div class="mod-name">Academia — Dragões</div>
<div><span class="badge badge-blue">Sub-23 · Sub-19 · Sub-17</span></div>
<p class="mod-desc">Uma das melhores academias da Península Ibérica. Formou jogadores como Vítor Baía, Deco, João Moutinho, Fábio Vieira, Fábio Silva e muitos outros internacionais portugueses.</p>
<div class="mod-news"></div>
<a href="https://dragonforce.fcporto.pt/" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
<div class="modality-card fade-up">
<div class="mod-icon"><i class="fa-solid fa-sailboat"></i></div>
<div class="mod-name">Vela</div>
<div><span class="badge badge-dark">Alto Rendimento</span></div>
<p class="mod-desc">A secção de vela do FC Porto tem tradição nas águas do Rio Douro e na costa atlântica, com participações em regatas nacionais e internacionais de referência.</p>
<div class="mod-news"></div>
<a href="https://www.fcporto.pt/pt/modalidades/vela/noticias" target="_blank" rel="noopener" class="mod-link">Ver notícias <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg></a>
</div>
</div>
</div>
</section>
</div><!-- /page-modalidades -->
<!-- ═══════════════════════════════════════════════════════════════
PAGE: TRANSFERÊNCIAS
═══════════════════════════════════════════════════════════════ -->
<div id="page-transferencias" class="page-content">
<div class="page-hero transfer-hero">
<div class="container">
<div class="transfer-hero-label"><i class="fa-solid fa-arrow-right-arrow-left"></i> Mercado de Transferências</div>
<h1 class="page-hero-title">Entradas & <span>Saídas</span></h1>
<p class="page-hero-sub">Todas as movimentações, rumores e confirmações do mercado de transferências do FC Porto.</p>
<div class="mod-hero-stats">
<div class="mod-hero-stat"><span class="mod-hero-stat-val">2025/26</span><span class="mod-hero-stat-lbl">Época Actual</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:var(--green)">Entradas</span><span class="mod-hero-stat-lbl">Reforços</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:var(--red)">Saídas</span><span class="mod-hero-stat-lbl">Partidas</span></div>
</div>
</div>
</div>
<section style="padding: 0 0 0">
<div class="container">
<div class="transfer-window">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
Janela de inverno fechada · Próxima abertura: Junho 2026 · Época 2025/26
</div>
<div class="transfers-cols">
<!-- ENTRADAS -->
<div>
<div class="transfers-col-title tc-arrivals">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="12 5 12 19"/><polyline points="19 12 12 19 5 12"/></svg>
Entradas
</div>
<div style="font-size:11px;color:var(--text-3);margin-bottom:12px">Verão 2025</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/froholdt.webp' alt='' onerror="this.parentElement.innerHTML='VF'" /></div>
<div class="transfer-info">
<div class="transfer-name">Victor Froholdt</div>
<div class="transfer-pos">Médio · 🇩🇰 Dinamarca</div>
<div class="transfer-club">← FC Copenhagen</div>
</div>
<div class="transfer-fee">€20M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/gabriveiga.webp' alt='' onerror="this.parentElement.innerHTML='GV'" /></div>
<div class="transfer-info">
<div class="transfer-name">Gabri Veiga</div>
<div class="transfer-pos">Médio Ofensivo · 🇪🇸 Espanha</div>
<div class="transfer-club">← Al-Ahli</div>
</div>
<div class="transfer-fee">€15M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/albertocosta.png' alt='' onerror="this.parentElement.innerHTML='AC'" /></div>
<div class="transfer-info">
<div class="transfer-name">Alberto Costa</div>
<div class="transfer-pos">Lateral-Dir · 🇵🇹 Portugal</div>
<div class="transfer-club">← Juventus</div>
</div>
<div class="transfer-fee">€15M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/perez.png' alt='' onerror="this.parentElement.innerHTML='NP'" /></div>
<div class="transfer-info">
<div class="transfer-name">Nehuén Pérez</div>
<div class="transfer-pos">Defesa Central · 🇦🇷 Argentina</div>
<div class="transfer-club">← Udinese</div>
</div>
<div class="transfer-fee">€13.3M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/borja.webp' alt='' onerror="this.parentElement.innerHTML='BS'" /></div>
<div class="transfer-info">
<div class="transfer-name">Borja Sainz</div>
<div class="transfer-pos">Extremo · 🇪🇸 Espanha</div>
<div class="transfer-club">← Norwich City</div>
</div>
<div class="transfer-fee">€13.3M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/bednarek.webp' alt='' onerror="this.parentElement.innerHTML='JB'" /></div>
<div class="transfer-info">
<div class="transfer-name">Jan Bednarek</div>
<div class="transfer-pos">Defesa Central · 🇵🇱 Polónia</div>
<div class="transfer-club">← Southampton</div>
</div>
<div class="transfer-fee">€7.5M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/Prpic.png' alt='' onerror="this.parentElement.innerHTML='DP'" /></div>
<div class="transfer-info">
<div class="transfer-name">Dominik Prpić</div>
<div class="transfer-pos">Extremo · 🇭🇷 Croácia</div>
<div class="transfer-club">← Hajduk Split</div>
</div>
<div class="transfer-fee">€4.5M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/pablorosario.webp' alt='' onerror="this.parentElement.innerHTML='PR'" /></div>
<div class="transfer-info">
<div class="transfer-name">Pablo Rosario</div>
<div class="transfer-pos">Médio Defensivo · 🇳🇱 Holanda</div>
<div class="transfer-club">← OGC Nice</div>
</div>
<div class="transfer-fee">€3.75M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/luukdejong.jpg' alt='' onerror="this.parentElement.innerHTML='LJ'" /></div>
<div class="transfer-info">
<div class="transfer-name">Luuk de Jong</div>
<div class="transfer-pos">Avançado · 🇳🇱 Holanda</div>
<div class="transfer-club">← PSV Eindhoven</div>
</div>
<div><span class="badge badge-dark" style="font-size:10px">Livre</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/karamoh.jpg' alt='' onerror="this.parentElement.innerHTML='YK'" /></div>
<div class="transfer-info">
<div class="transfer-name">Yann Karamoh</div>
<div class="transfer-pos">Extremo · 🇫🇷 França</div>
<div class="transfer-club">← Torino</div>
</div>
<div><span class="badge badge-dark" style="font-size:10px">Livre</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/kiwior.webp' alt='' onerror="this.parentElement.innerHTML='JK'" /></div>
<div class="transfer-info">
<div class="transfer-name">Jakub Kiwior</div>
<div class="transfer-pos">Defesa Central · 🇵🇱 Polónia</div>
<div class="transfer-club">← Arsenal</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/pedrolima.jpg' alt='' onerror="this.parentElement.innerHTML='PL'" /></div>
<div class="transfer-info">
<div class="transfer-name">Pedro Lima</div>
<div class="transfer-pos">Lateral-Dir · 🇵🇹 Portugal</div>
<div class="transfer-club">← Wolverhampton</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div style="font-size:11px;color:var(--text-3);margin:16px 0 12px">Janeiro 2026</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/pietuszewski.png' alt='' onerror="this.parentElement.innerHTML='OP'" /></div>
<div class="transfer-info">
<div class="transfer-name">Oskar Pietuszewski</div>
<div class="transfer-pos">Médio · 🇵🇱 Polónia</div>
<div class="transfer-club">← Jagiellonia</div>
</div>
<div class="transfer-fee">€9M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/thiagossilva.jpg' alt='' onerror="this.parentElement.innerHTML='TS'" /></div>
<div class="transfer-info">
<div class="transfer-name">Thiago Silva</div>
<div class="transfer-pos">Defesa Central · 🇧🇷 Brasil</div>
<div class="transfer-club">← Fluminense</div>
</div>
<div><span class="badge badge-dark" style="font-size:10px">Livre</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/moffi.png' alt='' onerror="this.parentElement.innerHTML='TM'" /></div>
<div class="transfer-info">
<div class="transfer-name">Terem Moffi</div>
<div class="transfer-pos">Avançado · 🇳🇬 Nigéria</div>
<div class="transfer-club">← OGC Nice</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/fofana.png' alt='' onerror="this.parentElement.innerHTML='SF'" /></div>
<div class="transfer-info">
<div class="transfer-name">Seko Fofana</div>
<div class="transfer-pos">Médio · 🇨🇮 Costa do Marfim</div>
<div class="transfer-club">← Rennes</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
</div>
<!-- SAÍDAS -->
<div>
<div class="transfers-col-title tc-departures">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="12 19 12 5"/><polyline points="5 12 12 5 19 12"/></svg>
Saídas
</div>
<div style="font-size:11px;color:var(--text-3);margin-bottom:12px">Verão 2025</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/979222/image' alt='' onerror="this.parentElement.innerHTML='FC'" /></div>
<div class="transfer-info">
<div class="transfer-name">Francisco Conceição</div>
<div class="transfer-pos">Extremo · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Juventus</div>
</div>
<div class="transfer-fee">€32M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/2062414/image' alt='' onerror="this.parentElement.innerHTML='OT'" /></div>
<div class="transfer-info">
<div class="transfer-name">Otávio</div>
<div class="transfer-pos">Médio · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Paris FC</div>
</div>
<div class="transfer-fee">€18M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/902031/image' alt='' onerror="this.parentElement.innerHTML='JM'" /></div>
<div class="transfer-info">
<div class="transfer-name">João Mário</div>
<div class="transfer-pos">Lateral-Dir · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Juventus</div>
</div>
<div class="transfer-fee">€12M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/goncaloborges.webp' alt='' onerror="this.parentElement.innerHTML='GB'" /></div>
<div class="transfer-info">
<div class="transfer-name">Gonçalo Borges</div>
<div class="transfer-pos">Extremo · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Feyenoord</div>
</div>
<div class="transfer-fee">€10M</div>
</div>
<div class="transfer-card fade-up">
<div class="transfer-avatar">FN</div>
<div class="transfer-info">
<div class="transfer-name">Fran Navarro</div>
<div class="transfer-pos">Avançado · 🇪🇸 Espanha</div>
<div class="transfer-club">→ Saída definitiva</div>
</div>
<div class="transfer-fee">€2.7M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/945448/image' alt='' onerror="this.style.display='none';this.parentElement.insertAdjacentText('beforeend','ZP')" /></div>
<div class="transfer-info">
<div class="transfer-name">Zé Pedro</div>
<div class="transfer-pos">Defesa Central · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Cagliari</div>
</div>
<div class="transfer-fee">€2M</div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/867440/image' alt='' onerror="this.parentElement.innerHTML='DN'" /></div>
<div class="transfer-info">
<div class="transfer-name">Danny Namaso</div>
<div class="transfer-pos">Extremo · 🇬🇧 Inglaterra</div>
<div class="transfer-club">→ AJ Auxerre</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/851286/image' alt='' onerror="this.style.display='none';this.parentElement.insertAdjacentText('beforeend','AF')" /></div>
<div class="transfer-info">
<div class="transfer-name">André Franco</div>
<div class="transfer-pos">Médio · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Chicago Fire</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/1586618/image' alt='' onerror="this.parentElement.innerHTML='VS'" /></div>
<div class="transfer-info">
<div class="transfer-name">Vasco Sousa</div>
<div class="transfer-pos">Médio · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Moreirense</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/marcano.jpg' alt='' onerror="this.parentElement.innerHTML='IM'" /></div>
<div class="transfer-info">
<div class="transfer-name">Iván Marcano</div>
<div class="transfer-pos">Defesa Central · 🇪🇸 Espanha</div>
<div class="transfer-club">→ Reforma</div>
</div>
<div><span class="badge badge-dark" style="font-size:10px">Fim Contrato</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/979222/image' alt='' onerror="this.style.display='none';this.parentElement.insertAdjacentText('beforeend','FC')" /></div>
<div class="transfer-info">
<div class="transfer-name">Fábio Cardoso</div>
<div class="transfer-pos">Defesa Central · 🇵🇹 Portugal</div>
<div class="transfer-club">→ Sevilla</div>
</div>
<div><span class="badge badge-dark" style="font-size:10px">Fim Contrato</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/grujic.jpg' alt='' onerror="this.parentElement.innerHTML='MG'" /></div>
<div class="transfer-info">
<div class="transfer-name">Marko Grujić</div>
<div class="transfer-pos">Médio · 🇷🇸 Sérvia</div>
<div class="transfer-club">→ AEK Atenas</div>
</div>
<div><span class="badge badge-dark" style="font-size:10px">Fim Contrato</span></div>
</div>
<div style="font-size:11px;color:var(--text-3);margin:16px 0 12px">Janeiro 2026</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/eustaquio.jpg' alt='' onerror="this.parentElement.innerHTML='SE'" /></div>
<div class="transfer-info">
<div class="transfer-name">Stephen Eustáquio</div>
<div class="transfer-pos">Médio · 🇨🇦 Canadá</div>
<div class="transfer-club">→ Los Angeles FC</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div class="transfer-card fade-up">
<div class="transfer-avatar">AA</div>
<div class="transfer-info">
<div class="transfer-name">Ángel Alarcón</div>
<div class="transfer-pos">Extremo · 🇪🇸 Espanha</div>
<div class="transfer-club">→ FC Utrecht</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/2362113/image' alt='' onerror="this.parentElement.innerHTML='TP'" /></div>
<div class="transfer-info">
<div class="transfer-name">Tomás Pérez</div>
<div class="transfer-pos">Médio · 🇦🇷 Argentina</div>
<div class="transfer-club">→ Atlético Mineiro</div>
</div>
<div><span class="badge badge-blue" style="font-size:10px">Empréstimo</span></div>
</div>
</div>
<!-- RUMORES -->
<div>
<div class="transfers-col-title tc-rumours">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
Rumores
</div>
<div style="font-size:11px;color:var(--text-3);margin-bottom:16px">Janela de Verão 2026 — especulação da imprensa</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/rodrigomora.webp' alt='' onerror="this.parentElement.innerHTML='RM'" /></div>
<div class="transfer-info">
<div class="transfer-name">Rodrigo Mora</div>
<div class="transfer-pos">Avançado · 🇵🇹 Portugal</div>
<div class="transfer-club">Porto → interesse europeu</div>
</div>
<div><span class="badge badge-gold" style="font-size:10px">★★★☆</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/borja.webp' alt='' onerror="this.style.display='none';this.parentElement.insertAdjacentText('beforeend','BS')" /></div>
<div class="transfer-info">
<div class="transfer-name">Borja Sainz</div>
<div class="transfer-pos">Extremo · 🇪🇸 Espanha</div>
<div class="transfer-club">Porto → Premier League</div>
</div>
<div><span class="badge badge-gold" style="font-size:10px">★★★☆</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='/players/gabriveiga.webp' alt='' onerror="this.style.display='none';this.parentElement.insertAdjacentText('beforeend','GV')" /></div>
<div class="transfer-info">
<div class="transfer-name">Gabri Veiga</div>
<div class="transfer-pos">Médio Ofensivo · 🇪🇸 Espanha</div>
<div class="transfer-club">Porto → possível venda</div>
</div>
<div><span class="badge badge-gold" style="font-size:10px">★★☆☆</span></div>
</div>
<div class="transfer-card fade-up">
<div class='transfer-avatar'><img src='https://api.sofascore.app/api/v1/player/904835/image' alt='' onerror="this.parentElement.innerHTML='FV'" /></div>
<div class="transfer-info">
<div class="transfer-name">Fábio Vieira</div>
<div class="transfer-pos">Médio Ofensivo · 🇵🇹 Portugal</div>
<div class="transfer-club">Arsenal → regresso Porto?</div>
</div>
<div><span class="badge badge-gold" style="font-size:10px">★★☆☆</span></div>
</div>
</div>
</div>
</div>
</section>
</div><!-- /page-transferencias -->
<!-- ═══════════════════════════════════════════════════════════════
PAGE: JOGOS EM DIRECTO
═══════════════════════════════════════════════════════════════ -->
<!-- ═══════════════════════════════════════════════════════════════
PAGE: CAPAS JORNAIS
═══════════════════════════════════════════════════════════════ -->
<div id="page-capas-jornais" class="page-content">
<div class="page-hero capas-hero">
<div class="container">
<div class="capas-hero-label"><i class="fa-solid fa-newspaper"></i> Imprensa Desportiva</div>
<h1 class="page-hero-title">Capas dos <span>Jornais</span></h1>
<p class="page-hero-sub">As primeiras páginas dos principais jornais desportivos portugueses. Actualizadas diariamente.</p>
<div class="mod-hero-stats">
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:#e8c840">Record</span><span class="mod-hero-stat-lbl">Jornal Desportivo</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:#e84040">A Bola</span><span class="mod-hero-stat-lbl">Jornal Desportivo</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:#4080e8">O Jogo</span><span class="mod-hero-stat-lbl">Jornal Desportivo</span></div>
</div>
</div>
</div>
<section style="padding: 0 0 0">
<div class="container">
<p class="newspapers-intro">
Aqui encontras as capas diárias dos jornais desportivos portugueses.
Clica em cada jornal para veres a edição de hoje completa.
</p>
<div class="newspapers-grid">
<!-- RECORD -->
<div class="newspaper-card fade-up">
<div class="newspaper-header">
<div class="newspaper-logo-box" style="background:rgba(220,38,38,0.12)">📰</div>
<div>
<div class="newspaper-name">Record</div>
<div class="newspaper-tagline">O jornal desportivo mais vendido</div>
</div>
</div>
<div class="newspaper-cover-area" id="cover-record">
<div class="newspaper-cover-emoji">📄</div>
<div class="newspaper-cover-lbl">A carregar capa…</div>
</div>
<div class="newspaper-footer-bar">
<span class="newspaper-date" id="newsDate1">A carregar data…</span>
<a href="https://www.record.pt" target="_blank" rel="noopener" class="btn-primary" style="padding:7px 14px;font-size:12px">
Ver Capa
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
</a>
</div>
</div>
<!-- A BOLA -->
<div class="newspaper-card fade-up">
<div class="newspaper-header">
<div class="newspaper-logo-box" style="background:rgba(234,179,8,0.12)">⚽</div>
<div>
<div class="newspaper-name">A Bola</div>
<div class="newspaper-tagline">O decano da imprensa desportiva</div>
</div>
</div>
<div class="newspaper-cover-area" id="cover-abola">
<div class="newspaper-cover-emoji">📄</div>
<div class="newspaper-cover-lbl">A carregar capa…</div>
</div>
<div class="newspaper-footer-bar">
<span class="newspaper-date" id="newsDate2">A carregar data…</span>
<a href="https://www.abola.pt" target="_blank" rel="noopener" class="btn-primary" style="padding:7px 14px;font-size:12px">
Ver Capa
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
</a>
</div>
</div>
<!-- O JOGO -->
<div class="newspaper-card fade-up">
<div class="newspaper-header">
<div class="newspaper-logo-box" style="background:rgba(59,130,246,0.12)">🗞️</div>
<div>
<div class="newspaper-name">O Jogo</div>
<div class="newspaper-tagline">O jornal do Norte de Portugal</div>
</div>
</div>
<div class="newspaper-cover-area" id="cover-ojogo">
<div class="newspaper-cover-emoji">📄</div>
<div class="newspaper-cover-lbl">A carregar capa…</div>
</div>
<div class="newspaper-footer-bar">
<span class="newspaper-date" id="newsDate3">A carregar data…</span>
<a href="https://ojogo.pt" target="_blank" rel="noopener" class="btn-primary" style="padding:7px 14px;font-size:12px">
Ver Capa
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
</a>
</div>
</div>
</div>
</div>
</section>
</div><!-- /page-capas-jornais -->
<!-- ═══════════════════════════════════════════════════════════════
PAGE: APOSTA DO DIA
═══════════════════════════════════════════════════════════════ -->
<div id="page-aposta-dia" class="page-content">
<div class="page-hero aposta-hero">
<div class="container">
<div class="aposta-hero-top">
<div class="aposta-hero-label"><i class="fa-solid fa-fire"></i> Em Parceria com</div>
<div class="aposta-betclic-wordmark">BET<span>CLIC</span></div>
</div>
<h1 class="page-hero-title">Aposta <span>do Dia</span></h1>
<p class="page-hero-sub">Análise diária e sugestão de aposta para o próximo jogo do FC Porto. Carácter informativo — 18+.</p>
<div class="mod-hero-stats">
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:var(--green)">70%</span><span class="mod-hero-stat-lbl">Taxa de Acerto</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:var(--bc)">9/13</span><span class="mod-hero-stat-lbl">Últimas Apostas</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:var(--gold)">Diária</span><span class="mod-hero-stat-lbl">Actualização</span></div>
</div>
</div>
</div>
<section style="padding: 0 0 0">
<div class="container">
<div class="bet-disclaimer">
<div class="bet-disclaimer-icon">⚠️</div>
<div>
<strong style="color:var(--gold)">Jogo Responsável — 18+</strong> — O conteúdo desta secção tem carácter meramente informativo e de entretenimento.
Apostar pode ser prejudicial. Se sentes que o jogo está a afectar a tua vida, procura ajuda:
<a href="https://www.jogoresponsavel.pt" target="_blank" rel="noopener" style="color:var(--gold);text-decoration:underline">jogoresponsavel.pt</a>.
Nunca aposta mais do que podes perder.
</div>
</div>
<div class="bet-main-grid">
<!-- MATCH CARD -->
<div class="bet-match-card">
<div class="bet-match-header">
<div>
<div class="bet-comp-label">🏆 Liga Portugal Betclic</div>
<div class="bet-comp-name">Jornada 34 — Último Jogo em Casa</div>
</div>
<div class="bet-match-date" style="color:var(--bc)">Sáb, 16 Mai • 15:30</div>
</div>
<div class="bet-match-body">
<div class="bet-teams">
<div class="bet-team">
<div class="bet-team-logo"><img src="https://a.espncdn.com/i/teamlogos/soccer/500/437.png" alt="FC Porto" style="width:62px;height:62px;object-fit:contain;"></div>
<div class="bet-team-name">FC Porto 🏆</div>
</div>
<div class="bet-vs">VS</div>
<div class="bet-team">
<div class="bet-team-logo"><img src="https://upload.wikimedia.org/wikipedia/en/thumb/3/37/C.D._Santa_Clara_logo.svg/250px-C.D._Santa_Clara_logo.svg.png" alt="Santa Clara" style="width:62px;height:62px;object-fit:contain;"></div>
<div class="bet-team-name">Santa Clara</div>
</div>
</div>
<div class="bet-pick">
<div class="bet-pick-icon">🎯</div>
<div>
<div class="bet-pick-label">A nossa sugestão</div>
<div class="bet-pick-value">Porto a Ganhar por 2+</div>
<div class="bet-pick-conf">Confiança: Alta ●●●●○</div>
</div>
</div>
<div class="bet-stats-grid">
<div class="bet-stat">
<div class="bet-stat-val">31º</div>
<div class="bet-stat-lbl">Campeões Nacionais</div>
</div>
<div class="bet-stat">
<div class="bet-stat-val">2.4</div>
<div class="bet-stat-lbl">Média golos em casa</div>
</div>
<div class="bet-stat">
<div class="bet-stat-val">84%</div>
<div class="bet-stat-lbl">Porto vence em casa</div>
</div>
</div>
<div style="margin-top:18px">
<p class="bet-analysis">
O Porto recebe o Santa Clara no último jogo em casa da temporada, já sagrado campeão pela 31ª vez. Os Dragões vão querer despedir-se do Estádio do Dragão com uma vitória festiva perante os seus adeptos.
O Santa Clara, já com a manutenção assegurada, não tem nada a perder, mas a diferença de qualidade é evidente. Esperamos um Porto motivado a festejar com a sua gente com pelo menos dois golos.
</p>
</div>
<a href="https://betclic.onelink.me/w4we/hjr4jsu1" target="_blank" rel="noopener sponsored" onclick="openBetclic(event)" style="display:block;margin-top:20px;border-radius:10px;overflow:hidden;">
<img src="/assets/betclic-banner-Bqa8MJUK.jpg" alt="Betclic — Ganha até 50€ de Boas-Vindas" style="width:100%;display:block;">
</a>
<p style="font-size:10px;color:var(--text-3);margin:5px 0 0">18+ · Publicidade · <a href="https://www.jogoresponsavel.pt" target="_blank" rel="noopener" style="color:var(--text-3)">jogoresponsavel.pt</a></p>
</div>
</div>
<!-- ODDS CARD -->
<div>
<div class="odds-card">
<div class="odds-card-header">
<div class="odds-card-title">Melhores Odds</div>
<div class="odds-pick-sum">Resultado Final</div>
</div>
<div class="odds-row">
<span class="odds-bookmaker">Santa Clara Vence</span>
<span class="odds-val" style="color:var(--text-2);font-size:18px">8.25</span>
</div>
<div class="odds-row">
<span class="odds-bookmaker">Empate</span>
<span class="odds-val" style="color:var(--text-2);font-size:18px">4.80</span>
</div>
<a class="odds-row-betclic" href="https://betclic.onelink.me/w4we/6mhydcgk" target="_blank" rel="noopener sponsored" onclick="openBetclic(event)">
<span class="odds-bookmaker">Porto Vence <span class="odds-betclic-badge">Parceiro Oficial</span></span>
<span class="odds-val">1.30</span>
</a>
<a class="betclic-cta-btn" href="https://betclic.onelink.me/w4we/6mhydcgk" target="_blank" rel="noopener sponsored" onclick="openBetclic(event)">
<i class="fa-solid fa-bolt"></i> APOSTAR NA BETCLIC
</a>
</div>
<div class="odds-card" style="margin-top:14px">
<div class="odds-card-header">
<div class="odds-card-title">Sugestão do Dia</div>
<div class="odds-pick-sum">Porto a Ganhar por 2+ Golos</div>
</div>
<div class="odds-row odds-hl">
<span class="odds-bookmaker">Lebull</span>
<span class="odds-val">1.85</span>
</div>
<div class="odds-row">
<span class="odds-bookmaker">Betano</span>
<span class="odds-val">1.83</span>
</div>
<a class="odds-row-betclic" href="https://betclic.onelink.me/w4we/6mhydcgk" target="_blank" rel="noopener sponsored" onclick="openBetclic(event)">
<span class="odds-bookmaker">Betclic <span class="odds-betclic-badge">Parceiro Oficial</span></span>
<span class="odds-val">1.89</span>
</a>
<div class="odds-row">
<span class="odds-bookmaker">Casino Portugal</span>
<span class="odds-val">1.80</span>
</div>
<a class="betclic-cta-btn" href="https://betclic.onelink.me/w4we/6mhydcgk" target="_blank" rel="noopener sponsored" onclick="openBetclic(event)">
<i class="fa-solid fa-bolt"></i> APOSTAR NA BETCLIC
</a>
</div>
</div>
</div>
<!-- HISTÓRICO -->
<div class="section-header">
<h2 class="section-title">Histórico de Apostas</h2>
<span class="badge badge-green">9 Wins / 4 Lost — Últimas 13 Apostas</span>
</div>
<div class="bet-past-grid" style="padding-bottom:60px">
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 1–0 Álverca · 02 Mai 🏆 CAMPEÕES</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.18</div>
<div class="bet-past-result res-win">✅ Ganhou · +€18.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 0–0 Sporting · 22 Abr 🏆 Taça SF</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.70</div>
<div class="bet-past-result res-loss">❌ Perdeu · -€100.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 2–0 Tondela · 19 Abr</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.30</div>
<div class="bet-past-result res-win">✅ Ganhou · +€30.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Estoril 1–3 Porto · 12 Abr</div>
<div class="bet-past-pick">Sugestão: Porto Vence Fora + Mais de 1.5 @ 1.92</div>
<div class="bet-past-result res-win">✅ Ganhou · +€92.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 2–2 Famalicão · 04 Abr</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.50</div>
<div class="bet-past-result res-loss">❌ Perdeu · -€100.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Braga 1–2 Porto · 22 Mar</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 2.25</div>
<div class="bet-past-result res-win">✅ Ganhou · +€125.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 2–0 Stuttgart · 19 Mar 🇪🇺</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.45</div>
<div class="bet-past-result res-win">✅ Ganhou · +€45.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 3–0 Moreirense · 15 Mar</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.22</div>
<div class="bet-past-result res-win">✅ Ganhou · +€22.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Stuttgart 1–2 Porto · 12 Mar 🇪🇺</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.75</div>
<div class="bet-past-result res-win">✅ Ganhou · +€75.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Benfica 2–2 Porto · 08 Mar</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 2.65</div>
<div class="bet-past-result res-loss">❌ Perdeu · -€100.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Sporting 1–0 Porto · 03 Mar 🏆</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 2.50</div>
<div class="bet-past-result res-loss">❌ Perdeu · -€100.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 3–1 Arouca · 27 Fev</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.25</div>
<div class="bet-past-result res-win">✅ Ganhou · +€25.00</div>
</div>
<div class="bet-past-card fade-up">
<div class="bet-past-match">Porto 1–0 Rio Ave · 22 Fev</div>
<div class="bet-past-pick">Sugestão: Porto Vence @ 1.15</div>
<div class="bet-past-result res-win">✅ Ganhou · +€15.00</div>
</div>
</div>
</div>
</section>
</div><!-- /page-aposta-dia -->
<!-- ═══════════════════════════════════════════════════════════════
PAGE: PLANTEL
═══════════════════════════════════════════════════════════════ -->
<div id="page-plantel" class="page-content">
<div class="page-hero" style="background:linear-gradient(160deg,#050c1e 0%,#0a1630 50%,#050c1e 100%);border-bottom:2px solid var(--blue)">
<div class="container" style="text-align:center">
<h1 class="page-hero-title">Plantel <span>2025/26</span></h1>
<p class="page-hero-sub">FC Porto — Campeões Nacionais · 31º Título · Época 2025/26</p>
<div class="mod-hero-stats">
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:var(--gold)">31º</span><span class="mod-hero-stat-lbl">Campeões</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val">22</span><span class="mod-hero-stat-lbl">Jogadores</span></div>
<div class="mod-hero-stat-div"></div>
<div class="mod-hero-stat"><span class="mod-hero-stat-val" style="color:var(--green)">85</span><span class="mod-hero-stat-lbl">Pontos</span></div>
</div>
</div>
</div>
<section style="padding:0 0 60px">
<div class="container">
<!-- FILTER TABS -->
<div style="display:flex;gap:8px;flex-wrap:wrap;margin:28px 0 24px">
<button class="squad-filter active" data-pos="todos">Todos</button>
<button class="squad-filter" data-pos="GR">Guarda-Redes</button>
<button class="squad-filter" data-pos="DEF">Defesas</button>
<button class="squad-filter" data-pos="MED">Médios</button>
<button class="squad-filter" data-pos="AV">Avançados</button>
</div>
<div class="squad-grid" id="squadGrid">
<!-- GUARDA-REDES -->
<div class="squad-card" data-group="GR">
<div class="squad-num">99</div>
<div class="squad-photo"><img src="/assets/diogocosta-D0RqC9vV.webp" alt="Diogo Costa" onerror="this.parentElement.innerHTML='<span class=sq-init>DC</span>'"></div>
<div class="squad-info">
<div class="squad-name">Diogo Costa</div>
<div class="squad-meta"><span class="squad-pos-badge gr">GR</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pt.png" alt="PT"></div>
<div class="squad-stats"><span>32 jogos</span><span class="squad-stat-sep">·</span><span>0 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="GR">
<div class="squad-num">14</div>
<div class="squad-photo"><img src="/assets/claudoramos-DJjpbBRU.png" alt="Cláudio Ramos" onerror="this.parentElement.innerHTML='<span class=sq-init>CR</span>'"></div>
<div class="squad-info">
<div class="squad-name">Cláudio Ramos</div>
<div class="squad-meta"><span class="squad-pos-badge gr">GR</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pt.png" alt="PT"></div>
<div class="squad-stats"><span>1 jogo</span><span class="squad-stat-sep">·</span><span>0 golos</span></div>
</div>
</div>
<!-- DEFESAS -->
<div class="squad-card" data-group="DEF">
<div class="squad-num">4</div>
<div class="squad-photo"><img src="/assets/kiwior-BU32YIR9.webp" alt="Jakub Kiwior" onerror="this.parentElement.innerHTML='<span class=sq-init>JK</span>'"></div>
<div class="squad-info">
<div class="squad-name">Jakub Kiwior</div>
<div class="squad-meta"><span class="squad-pos-badge def">DC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pl.png" alt="PL"></div>
<div class="squad-stats"><span>25 jogos</span><span class="squad-stat-sep">·</span><span>0 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="DEF">
<div class="squad-num">5</div>
<div class="squad-photo"><img src="/assets/bednarek-BI3jh68J.webp" alt="Jan Bednarek" onerror="this.parentElement.innerHTML='<span class=sq-init>JB</span>'"></div>
<div class="squad-info">
<div class="squad-name">Jan Bednarek</div>
<div class="squad-meta"><span class="squad-pos-badge def">DC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pl.png" alt="PL"></div>
<div class="squad-stats"><span>31 jogos</span><span class="squad-stat-sep">·</span><span>2 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="DEF">
<div class="squad-num">12</div>
<div class="squad-photo"><img src="/assets/zaidu-QOZLjn4E.webp" alt="Zaidu Sanusi" onerror="this.parentElement.innerHTML='<span class=sq-init>ZS</span>'"></div>
<div class="squad-info">
<div class="squad-name">Zaidu Sanusi</div>
<div class="squad-meta"><span class="squad-pos-badge def">DE</span> <img class="squad-flag" src="https://flagcdn.com/20x15/ng.png" alt="NG"></div>
<div class="squad-stats"><span>17 jogos</span><span class="squad-stat-sep">·</span><span>1 golo</span></div>
</div>
</div>
<div class="squad-card" data-group="DEF">
<div class="squad-num">18</div>
<div class="squad-photo"><img src="/assets/perez-B31oONUP.png" alt="Nehuén Pérez" onerror="this.parentElement.innerHTML='<span class=sq-init>NP</span>'"></div>
<div class="squad-info">
<div class="squad-name">Nehuén Pérez</div>
<div class="squad-meta"><span class="squad-pos-badge def">DC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/ar.png" alt="AR"></div>
<div class="squad-stats"><span>5 jogos</span><span class="squad-stat-sep">·</span><span>1 golo</span></div>
</div>
</div>
<div class="squad-card" data-group="DEF">
<div class="squad-num">20</div>
<div class="squad-photo"><img src="/assets/albertocosta-DqKCPwzm.png" alt="Alberto Costa" onerror="this.parentElement.innerHTML='<span class=sq-init>AC</span>'"></div>
<div class="squad-info">
<div class="squad-name">Alberto Costa</div>
<div class="squad-meta"><span class="squad-pos-badge def">DD</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pt.png" alt="PT"></div>
<div class="squad-stats"><span>27 jogos</span><span class="squad-stat-sep">·</span><span>1 golo</span></div>
</div>
</div>
<div class="squad-card" data-group="DEF">
<div class="squad-num">21</div>
<div class="squad-photo"><img src="/assets/Prpic-DnkwMyDX.png" alt="Dominik Prpić" onerror="this.parentElement.innerHTML='<span class=sq-init>DP</span>'"></div>
<div class="squad-info">
<div class="squad-name">Dominik Prpić</div>
<div class="squad-meta"><span class="squad-pos-badge def">DD</span> <img class="squad-flag" src="https://flagcdn.com/20x15/hr.png" alt="HR"></div>
<div class="squad-stats"><span>5 jogos</span><span class="squad-stat-sep">·</span><span>0 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="DEF">
<div class="squad-num">52</div>
<div class="squad-photo"><img src="/assets/martim-C8qAAVBA.webp" alt="Martim Fernandes" onerror="this.parentElement.innerHTML='<span class=sq-init>MF</span>'"></div>
<div class="squad-info">
<div class="squad-name">Martim Fernandes</div>
<div class="squad-meta"><span class="squad-pos-badge def">DD</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pt.png" alt="PT"></div>
<div class="squad-stats"><span>20 jogos</span><span class="squad-stat-sep">·</span><span>1 golo</span></div>
</div>
</div>
<div class="squad-card" data-group="DEF">
<div class="squad-num">74</div>
<div class="squad-photo"><img src="/assets/franciscomoura-Bzl_SFXF.webp" alt="Francisco Moura" onerror="this.parentElement.innerHTML='<span class=sq-init>FM</span>'"></div>
<div class="squad-info">
<div class="squad-name">Francisco Moura</div>
<div class="squad-meta"><span class="squad-pos-badge def">DD</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pt.png" alt="PT"></div>
<div class="squad-stats"><span>19 jogos</span><span class="squad-stat-sep">·</span><span>2 golos</span></div>
</div>
</div>
<!-- MÉDIOS -->
<div class="squad-card" data-group="MED">
<div class="squad-num">8</div>
<div class="squad-photo"><img src="/assets/froholdt-CDc1YRkg.webp" alt="Victor Froholdt" onerror="this.parentElement.innerHTML='<span class=sq-init>VF</span>'"></div>
<div class="squad-info">
<div class="squad-name">Victor Froholdt</div>
<div class="squad-meta"><span class="squad-pos-badge med">MC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/dk.png" alt="DK"></div>
<div class="squad-stats"><span>32 jogos</span><span class="squad-stat-sep">·</span><span>6 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="MED">
<div class="squad-num">10</div>
<div class="squad-photo"><img src="/assets/gabriveiga-B5bvrigN.webp" alt="Gabri Veiga" onerror="this.parentElement.innerHTML='<span class=sq-init>GV</span>'"></div>
<div class="squad-info">
<div class="squad-name">Gabri Veiga</div>
<div class="squad-meta"><span class="squad-pos-badge med">MC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/es.png" alt="ES"></div>
<div class="squad-stats"><span>29 jogos</span><span class="squad-stat-sep">·</span><span>3 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="MED">
<div class="squad-num">13</div>
<div class="squad-photo"><img src="/assets/pablorosario-CdFxbhaO.webp" alt="Pablo Rosario" onerror="this.parentElement.innerHTML='<span class=sq-init>PR</span>'"></div>
<div class="squad-info">
<div class="squad-name">Pablo Rosario</div>
<div class="squad-meta"><span class="squad-pos-badge med">MC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/do.png" alt="DO"></div>
<div class="squad-stats"><span>22 jogos</span><span class="squad-stat-sep">·</span><span>2 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="MED">
<div class="squad-num">22</div>
<div class="squad-photo"><img src="/assets/alanvarela-BO3trD3O.webp" alt="Alan Varela" onerror="this.parentElement.innerHTML='<span class=sq-init>AV</span>'"></div>
<div class="squad-info">
<div class="squad-name">Alan Varela</div>
<div class="squad-meta"><span class="squad-pos-badge med">MC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/ar.png" alt="AR"></div>
<div class="squad-stats"><span>28 jogos</span><span class="squad-stat-sep">·</span><span>2 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="MED">
<div class="squad-num">42</div>
<div class="squad-photo"><img src="/assets/fofana-BUt0Ysk9.png" alt="Seko Fofana" onerror="this.parentElement.innerHTML='<span class=sq-init>SF</span>'"></div>
<div class="squad-info">
<div class="squad-name">Seko Fofana</div>
<div class="squad-meta"><span class="squad-pos-badge med">MC</span> <img class="squad-flag" src="https://flagcdn.com/20x15/ci.png" alt="CI"></div>
<div class="squad-stats"><span>11 jogos</span><span class="squad-stat-sep">·</span><span>3 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="MED">
<div class="squad-num">86</div>
<div class="squad-photo"><img src="/assets/rodrigomora-CmWZuV51.webp" alt="Rodrigo Mora" onerror="this.parentElement.innerHTML='<span class=sq-init>RM</span>'"></div>
<div class="squad-info">
<div class="squad-name">Rodrigo Mora</div>
<div class="squad-meta"><span class="squad-pos-badge med">MO</span> <img class="squad-flag" src="https://flagcdn.com/20x15/pt.png" alt="PT"></div>
<div class="squad-stats"><span>26 jogos</span><span class="squad-stat-sep">·</span><span>1 golo</span></div>
</div>
</div>
<!-- AVANÇADOS -->
<div class="squad-card" data-group="AV">
<div class="squad-num">7</div>
<div class="squad-photo"><img src="/assets/williamgomes-CbeP5uGP.webp" alt="William Gomes" onerror="this.parentElement.innerHTML='<span class=sq-init>WG</span>'"></div>
<div class="squad-info">
<div class="squad-name">William Gomes</div>
<div class="squad-meta"><span class="squad-pos-badge av">EX</span> <img class="squad-flag" src="https://flagcdn.com/20x15/br.png" alt="BR"></div>
<div class="squad-stats"><span>26 jogos</span><span class="squad-stat-sep">·</span><span>8 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="AV">
<div class="squad-num">9</div>
<div class="squad-photo"><img src="/assets/samu-yEkHJqOs.webp" alt="Samu Aghehowa" onerror="this.parentElement.innerHTML='<span class=sq-init>SA</span>'"></div>
<div class="squad-info">
<div class="squad-name">Samu</div>
<div class="squad-meta"><span class="squad-pos-badge av">AV</span> <img class="squad-flag" src="https://flagcdn.com/20x15/es.png" alt="ES"></div>
<div class="squad-stats"><span>20 jogos</span><span class="squad-stat-sep">·</span><span>13 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="AV">
<div class="squad-num">11</div>
<div class="squad-photo"><img src="/assets/pepe-xHMB1ygn.webp" alt="Pepê" onerror="this.parentElement.innerHTML='<span class=sq-init>PP</span>'"></div>
<div class="squad-info">
<div class="squad-name">Pepê</div>
<div class="squad-meta"><span class="squad-pos-badge av">EX</span> <img class="squad-flag" src="https://flagcdn.com/20x15/br.png" alt="BR"></div>
<div class="squad-stats"><span>29 jogos</span><span class="squad-stat-sep">·</span><span>3 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="AV">
<div class="squad-num">17</div>
<div class="squad-photo"><img src="/assets/borja-BC5Zjsx0.webp" alt="Borja Sainz" onerror="this.parentElement.innerHTML='<span class=sq-init>BS</span>'"></div>
<div class="squad-info">
<div class="squad-name">Borja Sainz</div>
<div class="squad-meta"><span class="squad-pos-badge av">EX</span> <img class="squad-flag" src="https://flagcdn.com/20x15/es.png" alt="ES"></div>
<div class="squad-stats"><span>28 jogos</span><span class="squad-stat-sep">·</span><span>5 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="AV">
<div class="squad-num">27</div>
<div class="squad-photo"><img src="/assets/denisgul-CG9Wc5Ot.webp" alt="Deniz Gül" onerror="this.parentElement.innerHTML='<span class=sq-init>DG</span>'"></div>
<div class="squad-info">
<div class="squad-name">Deniz Gül</div>
<div class="squad-meta"><span class="squad-pos-badge av">EX</span> <img class="squad-flag" src="https://flagcdn.com/20x15/tr.png" alt="TR"></div>
<div class="squad-stats"><span>27 jogos</span><span class="squad-stat-sep">·</span><span>4 golos</span></div>
</div>
</div>
<div class="squad-card" data-group="AV">
<div class="squad-num">29</div>
<div class="squad-photo"><img src="/assets/moffi-DKq5UYtK.png" alt="Terem Moffi" onerror="this.parentElement.innerHTML='<span class=sq-init>TM</span>'"></div>
<div class="squad-info">
<div class="squad-name">Terem Moffi</div>
<div class="squad-meta"><span class="squad-pos-badge av">AV</span> <img class="squad-flag" src="https://flagcdn.com/20x15/ng.png" alt="NG"></div>
<div class="squad-stats"><span>9 jogos</span><span class="squad-stat-sep">·</span><span>1 golo</span></div>
</div>
</div>
</div>
</div>
</section>
</div><!-- /page-plantel -->
<!-- ═══════════════════════════════════════════════════════════════
PAGE: CALENDÁRIO
═══════════════════════════════════════════════════════════════ -->
<div id="page-calendario" class="page-content">
<div class="page-hero" style="background:linear-gradient(135deg,#051226 0%,#0a1e40 60%,#051226 100%);border-bottom:2px solid var(--blue)">
<div class="container" style="text-align:center">
<div style="display:inline-flex;align-items:center;gap:7px;background:var(--blue);color:#fff;font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;padding:4px 14px;border-radius:99px;margin-bottom:14px">● Época 2025/26</div>
<h1 class="page-hero-title">Calendário <span style="color:var(--blue-2)">Completo</span></h1>
<p class="page-hero-sub">Todos os jogos da época — resultados e próximos encontros</p>
</div>
</div>
<section class="section">
<div class="container">
<div class="cal-filters" id="calFilters">
<button class="cal-filter active" data-league="todos">Todos</button>
<button class="cal-filter" data-league="Liga Portugal Betclic">Liga Portugal</button>
<button class="cal-filter" data-league="UEFA Europa League">Europa League</button>
</div>
<div id="calList">
<div style="text-align:center;padding:60px 20px;color:var(--text-3)">A carregar calendário…</div>
</div>
</div>
</section>
</div><!-- /page-calendario -->
<!-- FOOTER -->
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<div class="nav-logo">
<div class="nav-logo-icon" style="width:46px;height:46px"><img src="/assets/logo-B3SSC6e3.jpg" alt="Porto Até Morrer"></div>
<div>
<div class="nav-logo-text" style="font-size:20px">Porto <span>Até Morrer</span></div>
<div class="nav-logo-sub">A Voz do Dragão desde 1893</div>
</div>
</div>
<p style="font-size:13px;color:var(--text-2);line-height:1.65;max-width:260px;margin:12px 0 16px">Site não oficial dedicado à actualidade do FC Porto. Feito por portistas, para portistas.</p>
<div class="footer-socials">
<a href="https://www.facebook.com/FCPATEAMORTE/" target="_blank" rel="noopener" aria-label="Facebook">
<svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor"><path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"/></svg>
</a>
<a href="https://www.instagram.com/portoatemorrer1893?igsh=ZGY2ZWdlbDdnNGcy" target="_blank" rel="noopener" aria-label="Instagram">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="2" y="2" width="20" height="20" rx="5"/><path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37z"/><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"/></svg>
</a>
</div>
</div>
<div class="footer-col">
<h4>FC Porto</h4>
<ul>
<li><a href="javascript:void(0)" data-page="plantel">Equipa</a></li>
<li><a href="#" onclick="navTo('calendario');return false;" data-page="calendario">Calendário</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Sobre Nós</h4>
<ul>
<li><a href="#">Quem Somos</a></li>
<li><a href="#">Contactos</a></li>
<li><a href="#">Publicidade</a></li>
<li><a href="#">Privacidade</a></li>
<li><a href="#">Termos de Uso</a></li>
</ul>
</div>
<div class="footer-classif">
<div class="footer-classif-label">🏆 Liga Portugal</div>
<div class="footer-classif-name">FC Porto · 1.º</div>
<div class="footer-classif-info" id="footerClassifInfo">76 pts · 29 jogos</div>
</div>
</div>
<div class="footer-bottom">
<p>© 2026 Porto Até Morrer. Site não oficial do FC Porto.</p>
<p class="heart">
Feito com
<svg width="13" height="13" viewBox="0 0 24 24" fill="var(--red)" stroke="var(--red)" stroke-width="1"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
por portistas
</p>
</div>
</div>
</footer>
<script>
// === DATE ===
const MONTHS = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];
const DAYS = ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'];
const now = new Date();
const dateEl = document.getElementById('topbarDate');
if (dateEl) dateEl.textContent = `${DAYS[now.getDay()]}, ${now.getDate()} ${MONTHS[now.getMonth()]} ${now.getFullYear()}`;
// === MOBILE MENU ===
function toggleMenu() {
const menu = document.getElementById('mobileMenu');
menu.classList.toggle('open');
document.body.style.overflow = menu.classList.contains('open') ? 'hidden' : '';
}
// === CATEGORY PILLS + FILTER ===
let allArticles = [];
function categorize(a) {
const text = (a.title + ' ' + (a.description || '')).toLowerCase();
const cat = (a.category || '').toLowerCase();
// Liga Europa: termos directos ou slug da notícia que menciona europa
if (/liga europa|europa league|uel|\beuropa\b/i.test(text)) return 'Liga Europa';
if (/liga portugal|primeira liga|liga pt|liga bwin|\bprimeira\b/i.test(text)) return 'Liga Portugal';
if (/transfer|contrat|renova|assina|reforç|compra|venda|emprést/i.test(text)) return 'Transferências';
if (/entrevista|diz que|afirma|declara|admite|confessa/i.test(text)) return 'Entrevistas';
if (/sub-\d|juvenis|academia|dragõezinhos|fc porto b|feminino/i.test(text + cat)) return 'Dragõezinhos';
return null;
}
function applyFilter(cat) {
if (cat === 'Todos') {
renderGrid(allArticles);
renderList(allArticles.slice(5));
return;
}
const filtered = allArticles.filter(a => categorize(a) === cat);
if (!filtered.length) {
document.getElementById('newsGrid').innerHTML =
`<p style="grid-column:1/-1;text-align:center;padding:60px 20px;color:var(--text-2)">Sem notícias em <strong>${cat}</strong> de momento.</p>`;
const list = document.getElementById('articleList');
if (list) list.innerHTML = '';
return;
}
renderGrid(filtered);
renderList(filtered.slice(5));
}
document.querySelectorAll('.cat-pill').forEach(pill => {
pill.addEventListener('click', function() {
document.querySelectorAll('.cat-pill').forEach(p => p.classList.remove('active'));
this.classList.add('active');
applyFilter(this.textContent.trim());
});
});
// === MODALITY NEWS — fcporto.pt API (CORS open, no proxy needed) ===
let modalityNewsLoaded = false
function slugify(text) {
return (text||'').normalize('NFD').replace(/[̀-ͯ]/g,'').toLowerCase()
.replace(/[^a-z0-9\s]/g,'').replace(/\s+/g,'-').replace(/-+/g,'-').trim()
}
function apiArticleUrl(dateStr, title) {
const d = new Date(dateStr.replace(' ','T'))
const ds = d.getFullYear() + String(d.getMonth()+1).padStart(2,'0') + String(d.getDate()).padStart(2,'0')
return `https://www.fcporto.pt/pt/noticias/${ds}-pt-${slugify(title)}`
}
function relativeTime(dateStr) {
const diff = (Date.now() - new Date(dateStr.replace(' ','T'))) / 1000
if (diff < 60) return 'agora'
if (diff < 3600) return `há ${Math.floor(diff/60)} min`
if (diff < 86400) return `há ${Math.floor(diff/3600)}h`
return `há ${Math.floor(diff/86400)} dias`
}
async function loadModalityNews() {
if (modalityNewsLoaded) return
modalityNewsLoaded = true
const cards = document.querySelectorAll('.modality-card[data-news-cat-id]')
await Promise.all([...cards].map(async card => {
const catId = card.dataset.newsCatId
const container = card.querySelector('.mod-news')
if (!container) return
container.innerHTML = '<span style="font-size:11px;color:var(--text-3);padding:4px 7px">A carregar…</span>'
try {
const r = await fetch(`https://api.app.fcporto.pt/v2/news?locale=pt&limit=5&category=${catId}`)
const d = await r.json()
const items = (d.data || []).slice(0, 2)
if (!items.length) { container.innerHTML = ''; return }
container.innerHTML = items.map(a => `
<a href="${apiArticleUrl(a.date, a.title)}" target="_blank" rel="noopener" class="mod-news-item">
<span class="mod-news-title">${a.title}</span>
<span class="mod-news-time">${relativeTime(a.date)}</span>
</a>`).join('')
} catch { container.innerHTML = '' }
}))
}
function populateModalityNews(articles) {
document.querySelectorAll('.modality-card[data-news-keyword]').forEach(card => {
const kw = card.dataset.newsKeyword;
const container = card.querySelector('.mod-news');
if (!container) return;
let matches;
if (kw === '*') {
matches = articles.slice(0, 2);
} else {
const kwLower = kw.toLowerCase();
matches = articles.filter(a => {
const text = (a.title + ' ' + (a.description || '') + ' ' + (a.category || '')).toLowerCase();
return text.includes(kwLower);
}).slice(0, 2);
}
if (!matches.length) { container.innerHTML = ''; return; }
container.innerHTML = matches.map(a => `
<a href="${a.link}" target="_blank" rel="noopener" class="mod-news-item">
<span class="mod-news-title">${a.title}</span>
${a.timeAgo ? `<span class="mod-news-time">${a.timeAgo}</span>` : ''}
</a>`).join('');
});
}
// === COUNTDOWNS ===
function formatCountdown(ms) {
if (ms <= 0) return 'A decorrer';
const d = Math.floor(ms / 86400000);
const h = Math.floor((ms % 86400000) / 3600000);
const m = Math.floor((ms % 3600000) / 60000);
if (d > 0) return `${d}d ${h}h ${m}m`;
if (h > 0) return `${h}h ${m}m`;
return `${m} min`;
}
function updateCountdowns() {
document.querySelectorAll('[data-target]').forEach(el => {
el.textContent = formatCountdown(new Date(el.dataset.target) - new Date());
});
}
updateCountdowns();
setInterval(updateCountdowns, 30000);
// === SCROLL ANIMATIONS ===
const io = new IntersectionObserver(entries => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
document.querySelectorAll('.fade-up').forEach(el => io.observe(el));
// === NAVBAR SCROLL ===
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
navbar.style.background = window.scrollY > 60
? 'rgba(7, 11, 20, 0.98)'
: 'rgba(7, 11, 20, 0.88)';
}, { passive: true });
// === NEWS FEED — Google News RSS via Vite proxy ===
function stripHtml(s) {
if (!s) return '';
// Step 1: decode HTML entities (textarea doesn't parse tags, only decodes entities)
const ta = document.createElement('textarea');
ta.innerHTML = s;
// Step 2: strip any remaining HTML tags
const div = document.createElement('div');
div.innerHTML = ta.value;
return (div.textContent || '').replace(/\s+/g,' ').trim();
}
function timeAgo(dateStr) {
const diff = (Date.now() - new Date(dateStr)) / 1000;
if (diff < 60) return 'agora';
if (diff < 3600) return `há ${Math.floor(diff/60)} min`;
if (diff < 86400) return `há ${Math.floor(diff/3600)}h`;
return `há ${Math.floor(diff/86400)} dias`;
}
function badgeFor(src) {
let s;
try { s = decodeURIComponent(src || '').toLowerCase(); } catch { s = (src || '').toLowerCase(); }
if (s.includes('record')) return ['badge-red', 'Record'];
if (s.includes('abola') || (s.includes('bola') && !s.includes('bola de')))
return ['badge-gold', 'A Bola'];
if (s.includes('maisfutebol')) return ['badge-blue', 'Maisfutebol'];
if (s.includes('o jogo') || s.includes('ojogo') || s.includes('o-jogo') || (s.includes('jogo') && s.includes('.pt')))
return ['badge-dark', 'O Jogo'];
if (s.includes('sapo')) return ['badge-blue', 'Sapo'];
if (s.includes('rtp')) return ['badge-red', 'RTP'];
if (s.includes('publico')) return ['badge-dark', 'Público'];
if (s.includes('sport') && s.includes('tv')) return ['badge-blue', 'SportTV'];
if (s.includes('fc porto') || s.includes('fcporto')) return ['badge-blue', 'FC Porto'];
// Fallback — extrair nome do domínio de forma legível
try {
const hostname = new URL(s.startsWith('http') ? s : 'https://' + s).hostname;
const name = hostname.replace(/^www\./, '').split('.')[0];
return ['badge-dark', name.charAt(0).toUpperCase() + name.slice(1)];
} catch {
return ['badge-dark', 'Notícia'];
}
}
async function fetchGNews() {
const r = await fetch('/api/news');
const d = await r.json();
if (!d.items) return [];
return d.items.map(item => ({
title: item.title || '',
link: item.link || '#',
pubDate: item.pubDate || '',
timeAgo: item.timeAgo || '',
description: item.description || '',
sourceName: item.sourceName || 'FC Porto',
badgeClass: item.badgeClass || 'badge-blue',
category: item.category || '',
img: item.imgSrc || '',
}));
}
function renderGrid(articles) {
const grid = document.getElementById('newsGrid');
if (!grid) return;
if (!articles.length) {
grid.innerHTML = '<p style="grid-column:1/-1;text-align:center;padding:60px;color:var(--text-2)">Sem notícias disponíveis de momento.</p>';
return;
}
const mkCard = (a, cls, delay) => {
const isFeat = cls.includes('featured');
const desc = stripHtml(a.description).substring(0, 180);
return `
<div class="card ${cls} fade-up" style="transition-delay:${delay}s">
<div class="card-img-wrap">${a.img
? `<img class="card-img" src="${a.img}" alt="${a.title}" loading="lazy">`
: `<div class="card-img-placeholder">🐉</div>`
}</div>
<div class="card-body">
<div class="card-meta">
<span class="badge ${a.badgeClass}">${a.sourceName}</span>
<span class="card-dot"></span>
<span class="card-time">${a.timeAgo || timeAgo(a.pubDate)}</span>
</div>
<a href="${a.link}" target="_blank" rel="noopener noreferrer">
<h3 class="card-title">${a.title}</h3>
</a>
${isFeat && desc ? `<p class="card-excerpt">${desc}…</p>` : ''}
<div class="card-footer">
<div class="card-author">
<div class="card-avatar">${a.sourceName[0]}</div>
<span class="card-author-name">${a.sourceName}</span>
</div>
</div>
</div>
</div>`;
};
grid.innerHTML =
mkCard(articles[0], 'card-featured', 0) +
articles.slice(1,5).map((a,i) => mkCard(a, '', (i+1)*0.09)).join('');
grid.querySelectorAll('.fade-up').forEach(el => io.observe(el));
}
function renderList(articles) {
const list = document.getElementById('articleList');
if (!list) return;
if (!articles.length) { list.innerHTML = ''; return; }
list.innerHTML = articles.slice(0,5).map((a,i) => `
<article class="article-item fade-up">
${a.img ? `<div class="article-thumb"><img src="${a.img}" alt="" loading="lazy"></div>` : ''}
<div class="article-body">
<div class="card-meta">
<span class="badge ${a.badgeClass}">${a.sourceName}</span>
<span class="card-dot"></span>
<span class="card-time">${a.timeAgo || timeAgo(a.pubDate)}</span>
</div>
<a href="${a.link}" target="_blank" rel="noopener noreferrer">
<h4 class="article-title">${a.title}</h4>
</a>
</div>
</article>`).join('');
list.querySelectorAll('.fade-up').forEach(el => io.observe(el));
}
function renderStandings(table) {
const el = document.getElementById('standingsTable');
if (!el || !table.length) return;
// CL = top 4, EL = 5, Relegation = last 3 (Liga Portugal 18 teams)
const total = table.length;
function posClass(p) {
if (p <= 4) return 'cl';
if (p === 5) return 'el';
if (p > total - 3) return 'rel';
return '';
}
el.innerHTML = `
<div class="standings-header">
<div>#</div><div>Equipa</div><div>J</div><div>V</div><div>D</div><div>Pts</div>
</div>
${table.map(t => `
<div class="standings-row${t.teamId === '437' ? ' porto' : ''}">
<div class="s-pos ${posClass(t.position)}">${t.position}</div>
<div class="s-name${t.teamId === '437' ? ' porto-name' : ''}">${t.teamName === 'AVS' ? 'AFS' : t.teamName}</div>
<div class="s-num">${t.gamesPlayed}</div>
<div class="s-num">${t.wins}</div>
<div class="s-num">${t.draws}</div>
<div class="s-pts">${t.points}</div>
</div>`).join('')}
`;
}
function renderTicker(articles) {
const track = document.getElementById('tickerTrack');
if (!track || !articles.length) return;
const titles = articles.slice(0, 10).map(a => a.title);
const all = [...titles, ...titles]; // duplicate for seamless loop
track.innerHTML = all.map(t => `<span>${t}</span>`).join('');
}
async function loadStats() {
try {
const r = await fetch('/api/standings');
const d = await r.json();
const s = d.stats || {};
const set = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val; };
set('statNum1', s.points || '—');
set('statNum2', s.rank ? s.rank + '.º' : '—');
set('statNum3', s.pointsFor || '—');
set('statNum4', s.gamesPlayed || '—');
renderStandings(d.table || []);
// Actualizar footer classificação
const fi = document.getElementById('footerClassifInfo');
if (fi && s.points && s.gamesPlayed) fi.textContent = `${s.points} pts · ${s.gamesPlayed} jogos`;
} catch { /* keep dashes */ }
}
async function loadNews() {
try {
const articles = await fetchGNews();
allArticles = articles;
renderTicker(articles);
applyFilter('Todos');
populateModalityNews(articles);
} catch(e) {
console.error('Erro notícias:', e);
document.getElementById('newsGrid').innerHTML =
'<p style="grid-column:1/-1;text-align:center;padding:60px;color:var(--text-2)">Não foi possível carregar notícias.</p>';
}
}
loadNews();
loadStats();
// === FIXTURES — TheSportsDB FC Porto (ID 134114) ===
function competitionLabel(league) {
const l = (league || '').toLowerCase();
if (l.includes('primeira') || l.includes('liga portugal')) return '🇵🇹 Liga Portugal Betclic';
if (l.includes('champions')) return '🏆 UEFA Champions League';
if (l.includes('europa')) return '🟠 UEFA Europa League';
if (l.includes('conference')) return '🟢 UEFA Conference League';
if (l.includes('taça') || l.includes('taca') || l.includes('cup')) return '🏆 Taça de Portugal';
if (l.includes('supertaça') || l.includes('supertaca') || l.includes('super cup')) return '🏆 Supertaça';
return '⚽ ' + (league || 'Competição');
}
function fmtMatchDate(isoDate) {
const dt = new Date(isoDate); // UTC → local auto-convert
const days = ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'];
const months = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];
const h = dt.getHours().toString().padStart(2,'0');
const m = dt.getMinutes().toString().padStart(2,'0');
return `${days[dt.getDay()]}, ${dt.getDate()} ${months[dt.getMonth()]} • ${h}:${m}`;
}
const BADGE_OVERRIDES = {
'Santa Clara': 'https://upload.wikimedia.org/wikipedia/en/thumb/3/37/C.D._Santa_Clara_logo.svg/250px-C.D._Santa_Clara_logo.svg.png',
};
function teamBadge(url, teamName) {
const overrideUrl = teamName && BADGE_OVERRIDES[teamName];
const src = overrideUrl || url;
if (!src) return '<span style="font-size:26px">⚽</span>';
return `<img src="${src}" style="width:34px;height:34px;object-fit:contain;filter:drop-shadow(0 1px 4px rgba(0,0,0,.5))" onerror="this.replaceWith(Object.assign(document.createElement('span'),{textContent:'⚽',style:'font-size:26px'}))">`;
}
async function loadFixtures() {
const scroll = document.getElementById('matchesScroll');
if (!scroll) return;
try {
const r = await fetch('/api/fixtures');
const d = await r.json();
const events = d.events || [];
if (!events.length) {
scroll.innerHTML = '<p style="padding:40px 20px;color:var(--text-2)">Sem jogos agendados de momento.</p>';
return;
}
scroll.innerHTML = events.slice(0, 8).map((ev, i) => {
const featured = i === 0 ? 'featured' : '';
const comp = competitionLabel(ev.strLeague);
const label = fmtMatchDate(ev.isoDate);
const target = ev.isoDate;
return `
<div class="match-card ${featured}">
<div class="match-competition">${comp}</div>
<div class="match-teams">
<div class="match-team">
<div class="match-team-logo">${teamBadge(ev.strHomeTeamBadge, ev.strHomeTeam)}</div>
<div class="match-team-name">${ev.strHomeTeam}</div>
</div>
<div class="match-vs">VS</div>
<div class="match-team">
<div class="match-team-logo">${teamBadge(ev.strAwayTeamBadge, ev.strAwayTeam)}</div>
<div class="match-team-name">${ev.strAwayTeam}</div>
</div>
</div>
<div class="match-time">
<div class="match-date">${label}</div>
<div class="match-countdown" data-target="${target}">—</div>
</div>
</div>`;
}).join('');
updateCountdowns();
} catch {
scroll.innerHTML = '<p style="padding:40px 20px;color:var(--text-2)">Não foi possível carregar os jogos.</p>';
}
}
loadFixtures();
// === CALENDAR ===
let calData = null;
let calLeagueFilter = 'todos';
async function loadCalendar() {
if (calData) { renderCalendar(); return; }
const list = document.getElementById('calList');
try {
const r = await fetch('/api/calendar');
const d = await r.json();
calData = d.games || [];
renderCalendar();
} catch {
list.innerHTML = '<p style="padding:40px 20px;color:var(--text-2)">Não foi possível carregar o calendário.</p>';
}
}
function renderCalendar() {
const list = document.getElementById('calList');
if (!list || !calData) return;
const now = new Date();
const MONTH_PT = ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'];
const DAY_PT = ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'];
const leagueIcon = l => {
if (l.includes('Liga Portugal')) return 'https://a.espncdn.com/i/leaguelogos/soccer/500/14.png';
if (l.includes('Europa')) return 'https://a.espncdn.com/i/leaguelogos/soccer/500/2310.png';
if (l.includes('Taça')) return 'https://a.espncdn.com/i/leaguelogos/soccer/500/23.png';
return '';
};
const games = calData.filter(g => calLeagueFilter === 'todos' || g.league === calLeagueFilter);
if (!games.length) {
list.innerHTML = '<p style="padding:40px 20px;text-align:center;color:var(--text-3)">Sem jogos para este filtro.</p>';
return;
}
// Find the EARLIEST upcoming game (closest to today), regardless of sort order
const upcoming = games.filter(g => !g.completed && new Date(g.date) > now);
upcoming.sort((a, b) => new Date(a.date) - new Date(b.date));
const nextId = upcoming[0]?.id;
const nextIdx = nextId ? games.findIndex(g => g.id === nextId) : -1;
let lastMonth = '';
let html = '';
games.forEach((g, i) => {
const dt = new Date(g.date);
const month = `${MONTH_PT[dt.getMonth()]} ${dt.getFullYear()}`;
if (month !== lastMonth) {
html += `<div class="cal-month">${month}</div>`;
lastMonth = month;
}
const day = DAY_PT[dt.getDay()];
const dateStr = `${day}, ${dt.getDate().toString().padStart(2,'0')}/${(dt.getMonth()+1).toString().padStart(2,'0')}<br><span style="font-size:10px">${dt.getHours().toString().padStart(2,'0')}:${dt.getMinutes().toString().padStart(2,'0')}</span>`;
const icon = leagueIcon(g.league);
const compImg = icon ? `<img class="cal-comp-icon" src="${icon}" alt="" onerror="this.style.display='none'">` : '<span style="font-size:14px">⚽</span>';
const CAL_BADGE_OVERRIDES = {
'Santa Clara': 'https://upload.wikimedia.org/wikipedia/en/thumb/3/37/C.D._Santa_Clara_logo.svg/250px-C.D._Santa_Clara_logo.svg.png',
};
const badgeImg = (src, name) => {
const override = name && CAL_BADGE_OVERRIDES[name];
const url = override || src;
return url ? `<img class="cal-team-badge" src="${url}" alt="${name}" onerror="this.style.opacity='.3'">` : '<span style="font-size:16px">⚽</span>';
};
const isNext = i === nextIdx;
const resultCls = g.result ? `result-${g.result}` : (isNext ? 'next-game' : '');
const score = g.completed
? `<div class="cal-score">${g.homeScore} — ${g.awayScore}</div>`
: `<div class="cal-score upcoming">${isNext ? '🔜' : 'vs'}</div>`;
let badge = '';
if (g.result) {
badge = `<div class="cal-result ${g.result}">${g.result}</div>`;
} else if (isNext) {
badge = `<div class="cal-result next">NEXT</div>`;
} else {
badge = `<div class="cal-result" style="opacity:0"></div>`;
}
html += `
<div class="cal-row ${resultCls}">
<div class="cal-date">${dateStr}</div>
${compImg}
<div class="cal-team">${badgeImg(g.homeBadge, g.homeTeam)}<span>${g.homeTeam}</span></div>
${score}
<div class="cal-team away"><span>${g.awayTeam}</span>${badgeImg(g.awayBadge, g.awayTeam)}</div>
${badge}
</div>`;
});
list.innerHTML = html;
}
// Calendar filter buttons
document.getElementById('calFilters')?.addEventListener('click', e => {
const btn = e.target.closest('.cal-filter');
if (!btn) return;
document.querySelectorAll('.cal-filter').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
calLeagueFilter = btn.dataset.league;
renderCalendar();
});
// === PAGE ROUTER ===
let currentPage = 'futebol';
function navTo(pageId) {
const target = document.getElementById('page-' + pageId);
if (!target) return;
// Hide all pages
document.querySelectorAll('.page-content').forEach(p => {
p.classList.remove('active');
});
// Show target
target.classList.add('active');
currentPage = pageId;
// Update nav active state
document.querySelectorAll('[data-page]').forEach(a => {
a.classList.toggle('active', a.dataset.page === pageId);
});
// Scroll to top
window.scrollTo({ top: 0, behavior: 'smooth' });
// Trigger fade-up animations on new page
target.querySelectorAll('.fade-up').forEach(el => io.observe(el));
// Load modality-specific news on first visit
if (pageId === 'modalidades') loadModalityNews();
// Newspaper dates
if (pageId === 'capas-jornais') updateNewsDates();
// Bet page match info
if (pageId === 'aposta-dia') updateBetPage();
// Calendar
if (pageId === 'calendario') loadCalendar();
}
// Bind all [data-page] links
// Squad filter
document.addEventListener('click', function(e) {
const btn = e.target.closest('.squad-filter');
if (btn) {
document.querySelectorAll('.squad-filter').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
const pos = btn.dataset.pos;
document.querySelectorAll('.squad-card').forEach(card => {
card.style.display = (pos === 'todos' || card.dataset.group === pos) ? '' : 'none';
});
}
});
document.addEventListener('click', function(e) {
const el = e.target.closest('[data-page]');
if (!el) return;
e.preventDefault();
const page = el.dataset.page;
const filter = el.dataset.filter;
navTo(page);
if (filter && page === 'futebol') {
document.querySelectorAll('.cat-pill').forEach(p => {
p.classList.toggle('active', p.textContent.trim() === filter);
});
applyFilter(filter);
}
const menu = document.getElementById('mobileMenu');
if (menu && menu.classList.contains('open')) toggleMenu();
});
// Newspaper dates + kiosko.net covers
function updateNewsDates() {
const now = new Date();
const months = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];
const label = 'Edição de ' + now.getDate() + ' ' + months[now.getMonth()] + ' ' + now.getFullYear();
for (let i = 1; i <= 3; i++) {
const el = document.getElementById('newsDate' + i);
if (el) el.textContent = label;
}
loadCovers();
}
let coversLoaded = false;
async function loadCovers() {
if (coversLoaded) return;
coversLoaded = true;
const map = { record: 'cover-record', abola: 'cover-abola', ojogo: 'cover-ojogo' };
// Show loading state
Object.values(map).forEach(id => {
const el = document.getElementById(id);
if (el) el.innerHTML = '<div class="newspaper-cover-lbl">A carregar capa…</div>';
});
try {
const covers = await fetch('/api/covers').then(r => r.json());
for (const [key, containerId] of Object.entries(map)) {
const url = covers[key];
const el = document.getElementById(containerId);
if (!url || !el) { if (el) el.innerHTML = '<div class="newspaper-cover-emoji" style="opacity:.2">📄</div><div class="newspaper-cover-lbl">Capa indisponível</div>'; continue; }
const img = new Image();
img.onload = () => { el.innerHTML = ''; el.classList.add('has-cover'); el.appendChild(img); };
img.onerror = () => { el.innerHTML = '<div class="newspaper-cover-emoji" style="opacity:.2">📄</div><div class="newspaper-cover-lbl">Capa indisponível</div>'; };
img.src = url;
}
} catch {
Object.values(map).forEach(id => {
const el = document.getElementById(id);
if (el) el.innerHTML = '<div class="newspaper-cover-emoji" style="opacity:.2">📄</div><div class="newspaper-cover-lbl">Capa indisponível</div>';
});
}
}
// ═══════════════════════════════════════════════
// BETCLIC INTEGRATION
// ═══════════════════════════════════════════════
const BETCLIC_URL = 'https://betclic.onelink.me/w4we/6mhydcgk';
const BETCLIC_HOMEPAGE = 'https://betclic.onelink.me/w4we/i428qudp';
const BETCLIC_ARTICLE = 'https://betclic.onelink.me/w4we/hjr4jsu1';
// Odds publicadas (referência para medir movimento)
const PUBLISHED_ODDS = { simple: 3.27, combined: 1.77 };
// Abre Betclic: app no mobile (Universal Link), popup no desktop
function openBetclic(e) {
e.preventDefault();
const url = e.currentTarget.href;
const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
if (isMobile) {
// Universal Link — iOS/Android abre a app Betclic se instalada
window.location.href = url;
} else {
const w = Math.min(1100, screen.availWidth - 40);
const h = Math.min(780, screen.availHeight - 60);
const left = Math.round((screen.availWidth - w) / 2);
const top = Math.round((screen.availHeight - h) / 2);
const popup = window.open(url, 'betclic_popup',
`width=${w},height=${h},left=${left},top=${top},scrollbars=yes,resizable=yes`);
if (!popup) window.open(url, '_blank');
}
}
// ── THE ODDS API CONFIG ──────────────────────────
// Regista grátis em: https://the-odds-api.com
// 500 calls/mês gratuitas — mete a key aqui:
const ODDS_API_KEY = ''; // ← colar key aqui
const ODDS_SPORT = 'soccer_uefa_europa_league';
const ODDS_BOOKMAKER = 'betclic_pt';
// ─────────────────────────────────────────────────
async function fetchLiveOdds() {
const elSimple = document.getElementById('oddsLiveBadgeSimple');
const elCombined = document.getElementById('oddsLiveBadgeCombined');
if (!elSimple && !elCombined) return;
// Sem API key → mostra estado neutro
if (!ODDS_API_KEY) {
[elSimple, elCombined].forEach(el => {
if (el) el.innerHTML = `<span class="odds-live-time" title="Adicionar API key para odds live">— live</span>`;
});
return;
}
try {
const url = `https://api.the-odds-api.com/v4/sports/${ODDS_SPORT}/odds/`
+ `?apiKey=${ODDS_API_KEY}®ions=eu&markets=h2h&bookmakers=${ODDS_BOOKMAKER}&oddsFormat=decimal`;
const res = await fetch(url, { signal: AbortSignal.timeout(8000) });
if (!res.ok) throw new Error('API error ' + res.status);
const data = await res.json();
// Encontra o evento Nottingham Forest vs Porto
const event = data.find(e =>
(e.home_team?.toLowerCase().includes('nottingham') || e.away_team?.toLowerCase().includes('nottingham')) &&
(e.home_team?.toLowerCase().includes('porto') || e.away_team?.toLowerCase().includes('porto'))
);
if (!event) throw new Error('evento não encontrado');
const bookmaker = event.bookmakers?.find(b => b.key === ODDS_BOOKMAKER);
if (!bookmaker) throw new Error('betclic não encontrado');
const h2h = bookmaker.markets?.find(m => m.key === 'h2h');
if (!h2h) throw new Error('mercado h2h não encontrado');
// Porto é o "away" team neste jogo
const portoOutcome = h2h.outcomes?.find(o =>
o.name?.toLowerCase().includes('porto')
);
const liveSimple = portoOutcome ? parseFloat(portoOutcome.price) : null;
renderOddsBadge(elSimple, liveSimple, PUBLISHED_ODDS.simple);
renderOddsBadge(elCombined, null, null);
} catch (err) {
console.warn('[Odds API]', err.message);
const t = new Date().toLocaleTimeString('pt-PT', { hour:'2-digit', minute:'2-digit' });
[elSimple, elCombined].forEach(el => {
if (el) el.innerHTML = `<span class="odds-live-time">✓ ${t}</span>`;
});
}
}
function renderOddsBadge(el, live, published) {
if (!el) return;
const t = new Date().toLocaleTimeString('pt-PT', { hour:'2-digit', minute:'2-digit' });
if (live == null || published == null) {
el.innerHTML = `<span class="odds-live-time">✓ ${t}</span>`;
return;
}
const diff = live - published;
const arrow = diff > 0.01 ? '⬆️' : diff < -0.01 ? '⬇️' : '➡️';
const cls = diff > 0.01 ? 'odds-live-up' : diff < -0.01 ? 'odds-live-down' : 'odds-live-same';
el.innerHTML = `<span class="${cls}">${arrow} ${live.toFixed(2)}</span><span class="odds-live-time">${t}</span>`;
}
// Corre ao carregar + refresca a cada 5 minutos
window.addEventListener('DOMContentLoaded', () => {
fetchLiveOdds();
setInterval(fetchLiveOdds, 5 * 60 * 1000);
});
// Bet page update
function updateBetPage() {
const el = document.getElementById('betMatchDate');
if (el) {
el.textContent = 'Qui, 16 Abr • 20:00';
}
// Try to get next opponent from fixtures already loaded
const matchCards = document.querySelectorAll('#matchesScroll .match-card');
if (matchCards.length) {
const firstCard = matchCards[0];
const teams = firstCard.querySelectorAll('.match-team-name');
if (teams.length === 2) {
const home = teams[0].textContent;
const away = teams[1].textContent;
const opp = home.includes('Porto') ? away : home;
const opEl = document.getElementById('betOpponent');
if (opEl && opp) opEl.textContent = opp;
}
}
}
</script>
<script>
document.addEventListener('DOMContentLoaded', () => { if (window.lucide) lucide.createIcons(); });
</script>
</body>
</html>
Sitemap
Кол-во: 0
XML-карта сайта для поисковиков
?
Sitemap.xml помогает поисковику быстрее находить и индексировать страницы. Особенно важен для крупных сайтов и новых страниц, на которые ещё нет входящих ссылок.
Robots.txt не содержит ссылку на карту сайта. Рекомендуется добавить карту сайта и указать ссылку на нее в robots.txt.
Внутренние ссылки
Не найдено
Ссылки на другие страницы своего сайта
?
Внутренние ссылки распределяют ссылочный вес между страницами и помогают поисковику обходить сайт. Пустые анкоры и ссылки на запрещённые robots.txt страницы — типичные ошибки.
Внутренних ссылок на странице 0 оптимально.
На странице присутствуют изображения 1.
Внешние ссылки
Кол-во: 21
Ссылки на сторонние сайты
?
Исходящие внешние ссылки передают часть ссылочного веса на чужие сайты. Ссылки на авторитетные ресурсы безопасны; ссылки на мусорные сайты могут навредить репутации страницы.
Внешних ссылок на странице 21 слишком много. Спрячьте лишние ссылки в тег noindex или атрибут rel='nofollow'!
Показать внешние ссылки
| Url | Анкор | Анализировать |
|---|---|---|
| facebook.com |
<svg width="14" height="14" viewbox="0 0 24 24" fill="currentColor"><path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"></path></svg>
|
|
| instagram.com |
<svg width="14" height="14" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="2" y="2" width="20" height="20" rx="5"></rect><path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg>
|
|
| fcporto.pt |
Ver mais
<svg width="14" height="14" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Site oficial
<svg width="14" height="14" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| dragonforce.fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| fcporto.pt |
Ver notícias <svg width="13" height="13" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M5 12h14M12 5l7 7-7 7"></path></svg>
|
Анализировать url |
| record.pt |
Ver Capa
<svg width="12" height="12" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>
|
Анализировать url |
| abola.pt |
Ver Capa
<svg width="12" height="12" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>
|
Анализировать url |
| ojogo.pt |
Ver Capa
<svg width="12" height="12" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>
|
Анализировать url |
| jogoresponsavel.pt |
jogoresponsavel.pt
|
Анализировать url |
| jogoresponsavel.pt |
jogoresponsavel.pt
|
Анализировать url |
| facebook.com |
<svg width="15" height="15" viewbox="0 0 24 24" fill="currentColor"><path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"></path></svg>
|
|
| instagram.com |
<svg width="15" height="15" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="2" y="2" width="20" height="20" rx="5"></rect><path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg>
|
Конкуренты Готовность: 0%
Конкуренты в Яндексе
Кол-во: 0
Топ сайтов-конкурентов в Яндексе
?
Сайты, чаще всего появляющиеся в ТОПе Яндекса по запросам из семантического ядра этой страницы.
Мы не нашли у вас конкурентов в Яндексе. Сайт или очень молодой или плохо продвигается.
Конкурентов в ТОП-10 Яндекса не нашлось.
Конкуренты в Google
Кол-во: 0
Топ сайтов-конкурентов в Google
?
Сайты, чаще всего появляющиеся в ТОПе Google по запросам из семантического ядра этой страницы.
Конкуренты в Google тоже не найдены. Займитесь продвижением сайта!
Конкурентов в ТОП-10 Google не нашлось.
ЗоЗПП: права потребителей Готовность: 100%
Нарушения
Не выявлены
Признаков дистанционной продажи товаров (интернет-магазина) не обнаружено — требования ЗоЗПП о раскрытии информации продавца к сайту не применяются. Нарушений нет.
ФЗ-149: рекомендательные технологии Готовность: 100%
Нарушения
Не выявлены
Рекомендательные блоки («с этим покупают», «похожие товары» и т.п.) на сайте не обнаружены — требования ст. 10.7 ФЗ-149 к сайту не применяются. Нарушений нет.
ФЗ-38: реклама Готовность: 100%
Нарушения
Не выявлены
Рекламных тематик с обязательными оговорками (медицина, БАД, кредиты и займы, новостройки) на сайте не обнаружено. Нарушений нет.
ФЗ-436: защита детей Готовность: 100%
Нарушения
Не выявлены
Признаков информационной продукции (новости, видео, книги, игры, курсы) не обнаружено — обязательная возрастная маркировка по ФЗ-436 сайту не требуется. Нарушений нет.
Вердикт
Сайт portoatemorrer.com не совсем готов к продвижению (процент готовности лишь 63%). Для попадания в ТОПы поисковых систем нужно:
Исправьте ошибки в мета-тегах.
Исправьте ошибки индексации.
Поделитесь с друзьями: