fix: correções Baixo da auditoria (escaping, dvh, transições, assets)
Fecha os itens 3.2.2, 3.3.1, 4.6, 5.2, 5.6, 5.7 e 7.4 do relatório de auditoria de 2026-09-24: escapa saídas de site_img_url()/canonical, valida identificadores de coluna em db_info_save(), troca 100vh por 100dvh, remove a última cor solta, encurta a transição para ~150ms, acrescenta decoding=async/fetchpriority=high nas imagens da home, e documenta as versões vendorizadas em ASSETS.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fcf86b60ea
commit
5cf0f14ad2
11 files changed
+69
-25
No files matched your search
+11
-11
@@ -53,7 +53,7 @@
|
||||
--fitme-shadow: 0 2px 20px rgba(11, 11, 13, .07);
|
||||
--fitme-shadow-lg: 0 8px 40px rgba(11, 11, 13, .13);
|
||||
--fitme-radius: 2px;
|
||||
--fitme-transition: 0.25s ease;
|
||||
--fitme-transition: 0.15s ease;
|
||||
}
|
||||
|
||||
/* ── Bootstrap 4 Overrides ─────────────────────────────────────────────────── */
|
||||
@@ -449,7 +449,7 @@ section[id] {
|
||||
/* ── Hero ──────────────────────────────────────────────────────────────────── */
|
||||
.hero-section {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -1968,7 +1968,7 @@ h3.contact-title {
|
||||
/* Hero */
|
||||
.hero-section {
|
||||
min-height: max(100svh, 500px);
|
||||
min-height: max(100vh, 500px);
|
||||
min-height: max(100dvh, 500px);
|
||||
}
|
||||
|
||||
.hero-text {
|
||||
@@ -2576,7 +2576,7 @@ h3.contact-title {
|
||||
max-width: 540px;
|
||||
min-height: 0;
|
||||
margin: 0 auto;
|
||||
max-height: calc(100vh - 48px);
|
||||
max-height: calc(100dvh - 48px);
|
||||
flex-direction: row;
|
||||
clip-path: none;
|
||||
transform: none;
|
||||
@@ -2600,7 +2600,7 @@ h3.contact-title {
|
||||
.md-card .ib-icon { width: 60px; height: 60px; margin-bottom: .8rem; }
|
||||
.md-card h3 { font-size: .95rem; }
|
||||
.md-body,
|
||||
.md-flip .md-body { max-height: calc(100vh - 48px); padding: 16px 16px 16px 14px; transform: none; }
|
||||
.md-flip .md-body { max-height: calc(100dvh - 48px); padding: 16px 16px 16px 14px; transform: none; }
|
||||
}
|
||||
|
||||
@media (max-width: 339px) {
|
||||
@@ -3127,7 +3127,7 @@ h3.contact-title {
|
||||
text-align: center;
|
||||
font-size: .85rem;
|
||||
font-weight: 600;
|
||||
color: #0B0B0D;
|
||||
color: var(--fitme-text);
|
||||
background: #ffd84d;
|
||||
}
|
||||
|
||||
@@ -3538,7 +3538,7 @@ h3.contact-title {
|
||||
max-width: 560px;
|
||||
min-height: 0;
|
||||
margin: 0 auto;
|
||||
max-height: calc(100vh - 48px);
|
||||
max-height: calc(100dvh - 48px);
|
||||
flex-direction: row;
|
||||
clip-path: none;
|
||||
transform: none;
|
||||
@@ -3561,7 +3561,7 @@ h3.contact-title {
|
||||
.td-photo { flex-basis: 34%; border-width: 3px; }
|
||||
.td-photo img { min-height: 180px; }
|
||||
.td-body,
|
||||
.td-flip .td-body { max-height: calc(100vh - 48px); padding: 16px 16px 16px 14px; transform: none; }
|
||||
.td-flip .td-body { max-height: calc(100dvh - 48px); padding: 16px 16px 16px 14px; transform: none; }
|
||||
}
|
||||
|
||||
@media (max-width: 339px) {
|
||||
@@ -4196,7 +4196,7 @@ h3.contact-title {
|
||||
/* Lightbox */
|
||||
.gal-lightbox {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
margin: 0;
|
||||
@@ -4219,7 +4219,7 @@ h3.contact-title {
|
||||
.gal-lb-figure {
|
||||
margin: 0;
|
||||
max-width: calc(100vw - 140px);
|
||||
max-height: calc(100vh - 80px);
|
||||
max-height: calc(100dvh - 80px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -4227,7 +4227,7 @@ h3.contact-title {
|
||||
|
||||
.gal-lb-figure img {
|
||||
max-width: 100%;
|
||||
max-height: calc(100vh - 110px);
|
||||
max-height: calc(100dvh - 110px);
|
||||
object-fit: contain;
|
||||
border-radius: var(--fitme-radius);
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
|
||||
|
||||
@@ -36,7 +36,7 @@ $brand = 'FitMe';
|
||||
</head>
|
||||
<body>
|
||||
<main class="wrap">
|
||||
<img src="<?= base_url('site/assets/img/logos/logo_black.svg') ?>" alt="<?= htmlspecialchars($brand) ?>" style="width:170px;filter:invert(1)">
|
||||
<img src="<?= base_url('site/assets/img/logos/logo_black.svg') ?>" alt="<?= htmlspecialchars($brand) ?>" style="width:170px;filter:invert(1)" decoding="async">
|
||||
<h1>Escolhe o teu <span>ginásio</span></h1>
|
||||
<div class="gyms">
|
||||
<?php foreach ($gyms as $g): ?>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="section-title">
|
||||
<h2><a href="https://journal.crossfit.com" target="_blank" title="CrossFit Journal: The Performance-Based Lifestyle Resource"> <img loading="lazy" src="https://de45qwmlmgefw.cloudfront.net/badges/black-300x150.png" width="300px" height="150" alt="CrossFit Journal: The Performance-Based Lifestyle Resource" /></a></h2>
|
||||
<h2><a href="https://journal.crossfit.com" target="_blank" title="CrossFit Journal: The Performance-Based Lifestyle Resource"> <img loading="lazy" decoding="async" src="https://de45qwmlmgefw.cloudfront.net/badges/black-300x150.png" width="300px" height="150" alt="CrossFit Journal: The Performance-Based Lifestyle Resource" /></a></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="container h-100">
|
||||
<div class="d-flex h-100 text-center align-items-center">
|
||||
<div class="w-100 text-white">
|
||||
<h1 class="display-3"><img src="<?= base_url('site/assets/img/logos/logo_crossfit_white.svg')?>" alt="CrossFit 3070 — box de CrossFit em Mira" style="opacity: .85; max-width: 320px;"></h1>
|
||||
<h1 class="display-3"><img src="<?= base_url('site/assets/img/logos/logo_crossfit_white.svg')?>" alt="CrossFit 3070 — box de CrossFit em Mira" style="opacity: .85; max-width: 320px;" decoding="async"></h1>
|
||||
<p class="lead mb-0"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -69,7 +69,7 @@ foreach ($rows as $d) { $grid[$d['dia_semana']][$d['hora_inicio']][] = $d; }
|
||||
<div class="schedule_cell<?= $value === $default_day ? '' : ' sched-hide' ?>" data-day="<?= htmlspecialchars($value) ?>" data-section="<?= ((int) substr($time, 0, 2) < 12) ? 'manha' : 'tarde' ?>" style="grid-column:<?= $col ?>;grid-row:<?= $row_of[$time] ?>;">
|
||||
<?php foreach ($grid[$value][$time] as $d): ?>
|
||||
<div class="schedule_box" style="background-color:<?= htmlspecialchars((string) $d['cor']) ?>">
|
||||
<img src="<?= site_img_url($d['icon'], 'uploads/modalidades/icons') ?>" alt="<?= htmlspecialchars((string) $d['nome']) ?>">
|
||||
<img src="<?= htmlspecialchars(site_img_url($d['icon'], 'uploads/modalidades/icons')) ?>" alt="<?= htmlspecialchars((string) $d['nome']) ?>" decoding="async">
|
||||
<a><b><?= htmlspecialchars((string) $d['nome']) ?></b></a>
|
||||
<div class="schedule_info">
|
||||
<?= htmlspecialchars((string) $d['hora_inicio']) ?>
|
||||
|
||||
@@ -41,7 +41,7 @@ $canonical = $GLOBALS['_canonical_override'] ?? match ($page) {
|
||||
<meta name="author" content="FitMe 3070">
|
||||
<meta name="theme-color" content="#C2D500">
|
||||
<title><?= htmlspecialchars($page_title) ?></title>
|
||||
<link rel="canonical" href="<?= $canonical ?>">
|
||||
<link rel="canonical" href="<?= htmlspecialchars($canonical) ?>">
|
||||
<?php if (seo_noindex()): /* staging copies (e.g. fitme.andmore.pt) must not compete with the real domain */ ?>
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<?php endif; ?>
|
||||
@@ -51,7 +51,7 @@ $canonical = $GLOBALS['_canonical_override'] ?? match ($page) {
|
||||
<link rel="dns-prefetch" href="https://forms.zohopublic.eu">
|
||||
<?php if (($current_uri_2 ?? '') === ''): ?>
|
||||
<!-- Homepage hero is the LCP image — start fetching it before the CSS/JS -->
|
||||
<link rel="preload" as="image" href="<?= base_url(($gym_meta['hero_image'] ?? '') !== '' ? $gym_meta['hero_image'] : 'site/assets/img/home.jpg') ?>">
|
||||
<link rel="preload" as="image" fetchpriority="high" href="<?= htmlspecialchars(base_url(($gym_meta['hero_image'] ?? '') !== '' ? $gym_meta['hero_image'] : 'site/assets/img/home.jpg')) ?>">
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Fonts -->
|
||||
@@ -72,7 +72,7 @@ $canonical = $GLOBALS['_canonical_override'] ?? match ($page) {
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="<?= base_url('site/assets/img/logos/apple-touch-icon.png') ?>">
|
||||
|
||||
<!-- Open Graph / link previews -->
|
||||
<meta property="og:url" content="<?= $canonical ?>">
|
||||
<meta property="og:url" content="<?= htmlspecialchars($canonical) ?>">
|
||||
<meta property="og:type" content="<?= htmlspecialchars($GLOBALS['_og_type_override'] ?? 'website') ?>">
|
||||
<meta property="og:site_name" content="FitMe 3070">
|
||||
<meta property="og:locale" content="pt_PT">
|
||||
|
||||
@@ -10,7 +10,7 @@ else
|
||||
<header class="header-section lazy">
|
||||
<nav class="navbar navbar-expand-lg navbar-light" style="padding-left:1rem; padding-top: 0; padding-bottom: 0;padding-right: 0; ">
|
||||
<a class="navbar-brand" href="<?= htmlspecialchars(gym_url(current_gym())) ?>">
|
||||
<img loading="eager" alt="Logo FitMe3070" src="<?= $logo ?>" style="width: 150px;">
|
||||
<img loading="eager" decoding="async" alt="Logo FitMe3070" src="<?= $logo ?>" style="width: 150px;">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
|
||||
+5
-5
@@ -98,7 +98,7 @@ if ($offer):
|
||||
<div class="col-6 col-sm-4 col-lg-3">
|
||||
<div class="icon-box-item">
|
||||
<div class="ib-icon">
|
||||
<img loading="lazy" src="<?= site_img_url($o['o_img'], 'uploads/website/offer') ?>" alt="<?= htmlspecialchars((string) $o['o_title']) ?>">
|
||||
<img loading="lazy" decoding="async" src="<?= htmlspecialchars(site_img_url($o['o_img'], 'uploads/website/offer')) ?>" alt="<?= htmlspecialchars((string) $o['o_title']) ?>">
|
||||
</div>
|
||||
<h3><?= htmlspecialchars((string) $o['o_title']) ?></h3>
|
||||
<p><?= htmlspecialchars((string) $o['o_description']) ?></p>
|
||||
@@ -201,20 +201,20 @@ if ($team):
|
||||
$t_certs = text_lines($d['certifications'] ?? '');
|
||||
$t_bio = trim(strip_tags((string) ($d['description'] ?? ''))) !== '' ? clean_richtext((string) $d['description']) : '';
|
||||
$t_detail = $t_skills || $t_certs || $t_bio !== '';
|
||||
$t_img = site_img_url($d['photo'], 'uploads/team/foto');
|
||||
$t_img = htmlspecialchars(site_img_url($d['photo'], 'uploads/team/foto'));
|
||||
$t_id = 'td-' . (int) $d['id'];
|
||||
?>
|
||||
<div class="col-6 col-md-4 col-lg-3" style="margin-top: 20px;">
|
||||
<div class="trainer-item<?= $t_detail ? ' has-detail' : '' ?>"<?= $t_detail ? ' tabindex="0" role="button" aria-expanded="false" aria-controls="' . $t_id . '" aria-label="Ver detalhes de ' . htmlspecialchars((string) $d['name']) . '"' : '' ?>>
|
||||
<div class="trainer-pic">
|
||||
<img loading="lazy" src="<?= $t_img ?>" alt="<?= htmlspecialchars((string) $d['name']) ?>">
|
||||
<img loading="lazy" decoding="async" src="<?= $t_img ?>" alt="<?= htmlspecialchars((string) $d['name']) ?>">
|
||||
</div>
|
||||
<h3><?= htmlspecialchars((string) $d['name']) ?></h3>
|
||||
<?php if ($t_title !== ''): ?><p class="trainer-title"><?= htmlspecialchars($t_title) ?></p><?php endif; ?>
|
||||
<?php if ($t_detail): ?>
|
||||
<div class="trainer-detail" id="<?= $t_id ?>">
|
||||
<button type="button" class="td-close" aria-label="Fechar">×</button>
|
||||
<div class="td-photo"><img loading="lazy" src="<?= $t_img ?>" alt=""></div>
|
||||
<div class="td-photo"><img loading="lazy" decoding="async" src="<?= $t_img ?>" alt=""></div>
|
||||
<div class="td-body">
|
||||
<strong class="td-name"><?= htmlspecialchars((string) $d['name']) ?></strong>
|
||||
<?php if ($t_title !== ''): ?><span class="td-title"><?= htmlspecialchars($t_title) ?></span><?php endif; ?>
|
||||
@@ -333,7 +333,7 @@ if (!in_array($default_day, $week_values, true)) { $default_day = $week_values[0
|
||||
<div class="schedule_cell<?= $value === $default_day ? '' : ' sched-hide' ?>" data-day="<?= htmlspecialchars($value) ?>" data-section="<?= ((int) substr($time, 0, 2) < 12) ? 'manha' : 'tarde' ?>" style="grid-column:<?= $col ?>;grid-row:<?= $row_of[$time] ?>;">
|
||||
<?php foreach ($grid[$value][$time] as $d): ?>
|
||||
<div class="schedule_box" style="background-color:<?= htmlspecialchars((string) $d['cor']) ?>">
|
||||
<img src="<?= site_img_url($d['icon'], 'uploads/modalidades/icons') ?>" alt="<?= htmlspecialchars((string) $d['nome']) ?>">
|
||||
<img src="<?= htmlspecialchars(site_img_url($d['icon'], 'uploads/modalidades/icons')) ?>" alt="<?= htmlspecialchars((string) $d['nome']) ?>" decoding="async">
|
||||
<a><b><?= htmlspecialchars((string) $d['nome']) ?></b></a>
|
||||
<div class="schedule_info">
|
||||
<?= htmlspecialchars((string) $d['hora_inicio']) ?>
|
||||
|
||||
Reference in new issue
Block a user