release: promote beta to main (gyms, brand colours, JPEG XL, SEO per gym) #3
No files matched your search
+2
-1
@@ -16,7 +16,8 @@ $GLOBALS['_gym'] = $gym;
|
|||||||
$info = site_info($pdo, (int) $gym['id']);
|
$info = site_info($pdo, (int) $gym['id']);
|
||||||
$navbar = site_navbar($gym);
|
$navbar = site_navbar($gym);
|
||||||
$current_uri_2 = $current_uri_2 ?? '';
|
$current_uri_2 = $current_uri_2 ?? '';
|
||||||
$GLOBALS['_view_shared'] = compact('info', 'navbar', 'current_uri_2', 'gym');
|
$nav_center_logo = $nav_center_logo ?? false; // index.php: big centred logo (navbar.php)
|
||||||
|
$GLOBALS['_view_shared'] = compact('info', 'navbar', 'current_uri_2', 'gym', 'nav_center_logo');
|
||||||
|
|
||||||
echo view('include'); // renders view('seo') inside <head>
|
echo view('include'); // renders view('seo') inside <head>
|
||||||
echo view('navbar');
|
echo view('navbar');
|
||||||
|
|||||||
+51
-18
@@ -365,14 +365,17 @@ section[id] {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Underline: a short bar with slashed ends (top-left and bottom-right cut, like
|
||||||
|
the "in" box of the FitMe in logo), tucked right under the text. */
|
||||||
.nav-link:after {
|
.nav-link:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -2px;
|
bottom: 3px;
|
||||||
left: 0;
|
left: var(--bs-navbar-nav-link-padding-x, .5rem);
|
||||||
width: 100%;
|
right: var(--bs-navbar-nav-link-padding-x, .5rem);
|
||||||
height: 2px;
|
height: 4px;
|
||||||
background: var(--fitme-accent);
|
background: var(--fitme-accent);
|
||||||
|
clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
|
||||||
transform: scaleX(0);
|
transform: scaleX(0);
|
||||||
transform-origin: left;
|
transform-origin: left;
|
||||||
transition: transform var(--fitme-transition);
|
transition: transform var(--fitme-transition);
|
||||||
@@ -590,6 +593,25 @@ section[id] {
|
|||||||
to { background-position: 150% 0; }
|
to { background-position: 150% 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Brand logo: 150px in the bar. On the home page (.has-center-logo) it starts
|
||||||
|
bigger on its own centred row (.is-top) and docks back on scroll (navbar.php). */
|
||||||
|
.navbar-brand img {
|
||||||
|
width: 150px;
|
||||||
|
height: auto;
|
||||||
|
transition: width .35s ease;
|
||||||
|
}
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
.header-section.is-top .navbar { flex-wrap: wrap; }
|
||||||
|
.header-section.is-top .navbar-brand {
|
||||||
|
flex: 0 0 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 14px 1rem 0 0; /* 1rem offsets the nav's left padding: true centre */
|
||||||
|
}
|
||||||
|
.header-section.is-top .navbar-brand img { width: 240px; }
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
.header-section::before, .header-section::after { animation: none; }
|
.header-section::before, .header-section::after { animation: none; }
|
||||||
}
|
}
|
||||||
@@ -3247,19 +3269,33 @@ h3.contact-title {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
width: min(640px, 92vw);
|
width: min(640px, 92vw);
|
||||||
padding: 12px 14px 12px 18px;
|
min-height: 88px;
|
||||||
background: rgba(11, 11, 13, .55);
|
padding: 18px 18px 18px 22px;
|
||||||
|
background: linear-gradient(90deg, rgba(11, 11, 13, .62), rgba(11, 11, 13, .42));
|
||||||
border: 1.5px solid rgba(var(--fitme-accent-rgb), .55);
|
border: 1.5px solid rgba(var(--fitme-accent-rgb), .55);
|
||||||
border-radius: 999px;
|
|
||||||
backdrop-filter: blur(8px);
|
|
||||||
-webkit-backdrop-filter: blur(8px);
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
animation: hero-event-glow 2.8s ease-in-out infinite;
|
animation: hero-event-glow 2.8s ease-in-out infinite;
|
||||||
transition: transform var(--fitme-transition), box-shadow var(--fitme-transition), border-color var(--fitme-transition);
|
transition: transform var(--fitme-transition), box-shadow var(--fitme-transition), border-color var(--fitme-transition);
|
||||||
}
|
}
|
||||||
/* The event's own image as a frosted (blurred + darkened) backdrop inside the
|
/* Defocus gradient: ::after blurs whatever is behind it (the event image in
|
||||||
pill — only when --ev-img is set; otherwise the translucent dark bg shows. */
|
::before, or the hero photo through the translucent bg), masked so the left is
|
||||||
|
sharp and the right most out of focus. .hero-event itself must not get
|
||||||
|
filter/backdrop-filter/opacity/mask, or it becomes the backdrop root and the
|
||||||
|
blur stops reaching the hero photo. */
|
||||||
|
.hero-event::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
-webkit-backdrop-filter: blur(14px);
|
||||||
|
backdrop-filter: blur(14px);
|
||||||
|
-webkit-mask-image: linear-gradient(90deg, transparent 10%, #000 90%);
|
||||||
|
mask-image: linear-gradient(90deg, transparent 10%, #000 90%);
|
||||||
|
}
|
||||||
|
/* The event's own image as a darkened backdrop inside the card, only when
|
||||||
|
--ev-img is set; otherwise the translucent dark bg shows. */
|
||||||
.hero-event.has-img::before {
|
.hero-event.has-img::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -3268,11 +3304,11 @@ h3.contact-title {
|
|||||||
background-image: var(--ev-img);
|
background-image: var(--ev-img);
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
filter: blur(6px) saturate(1.15) brightness(.5);
|
filter: saturate(1.15) brightness(.5);
|
||||||
transform: scale(1.18); /* hide the blur's transparent edges */
|
transform: scale(1.04);
|
||||||
transition: transform var(--fitme-transition);
|
transition: transform var(--fitme-transition);
|
||||||
}
|
}
|
||||||
.hero-event.has-img:hover::before { transform: scale(1.24); }
|
.hero-event.has-img:hover::before { transform: scale(1.1); }
|
||||||
/* Keep the content above the image layer. */
|
/* Keep the content above the image layer. */
|
||||||
.hero-event > * { position: relative; z-index: 1; }
|
.hero-event > * { position: relative; z-index: 1; }
|
||||||
@keyframes hero-event-glow {
|
@keyframes hero-event-glow {
|
||||||
@@ -3296,7 +3332,6 @@ h3.contact-title {
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: var(--fitme-accent);
|
color: var(--fitme-accent);
|
||||||
background: rgba(var(--fitme-accent-rgb), .14);
|
background: rgba(var(--fitme-accent-rgb), .14);
|
||||||
border-radius: 999px;
|
|
||||||
}
|
}
|
||||||
.hero-event-text {
|
.hero-event-text {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
@@ -3331,7 +3366,6 @@ h3.contact-title {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
color: var(--fitme-dark);
|
color: var(--fitme-dark);
|
||||||
background: var(--ev-accent);
|
background: var(--ev-accent);
|
||||||
border-radius: 999px;
|
|
||||||
}
|
}
|
||||||
.hero-event-go i { transition: transform var(--fitme-transition); }
|
.hero-event-go i { transition: transform var(--fitme-transition); }
|
||||||
.hero-event:hover .hero-event-go i { transform: translateX(4px); }
|
.hero-event:hover .hero-event-go i { transform: translateX(4px); }
|
||||||
@@ -3341,9 +3375,8 @@ h3.contact-title {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-radius: 18px;
|
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 14px;
|
padding: 18px 14px;
|
||||||
}
|
}
|
||||||
.hero-event-text { flex-basis: 100%; align-items: center; }
|
.hero-event-text { flex-basis: 100%; align-items: center; }
|
||||||
.hero-event-title, .hero-event-sub { white-space: normal; }
|
.hero-event-title, .hero-event-sub { white-space: normal; }
|
||||||
|
|||||||
@@ -9,14 +9,17 @@ else
|
|||||||
}
|
}
|
||||||
$logo = base_url($logo_rel);
|
$logo = base_url($logo_rel);
|
||||||
$logo_dims = svg_img_dims_attr(dirname(__DIR__, 2) . '/' . $logo_rel);
|
$logo_dims = svg_img_dims_attr(dirname(__DIR__, 2) . '/' . $logo_rel);
|
||||||
|
// Home page: the logo starts big and centred over the hero (.is-top) and docks
|
||||||
|
// back to the left of the bar once the page scrolls (script below).
|
||||||
|
$center_logo = !empty($nav_center_logo);
|
||||||
?>
|
?>
|
||||||
<header class="header-section lazy">
|
<header class="header-section lazy<?= $center_logo ? ' has-center-logo is-top' : '' ?>">
|
||||||
<nav class="navbar navbar-expand-lg navbar-light" style="padding-left:1rem; padding-top: 0; padding-bottom: 0;padding-right: 0; ">
|
<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())) ?>">
|
<a class="navbar-brand" href="<?= htmlspecialchars(gym_url(current_gym())) ?>">
|
||||||
<?php if (img_fallback_rel($logo_rel) !== ''): ?>
|
<?php if (img_fallback_rel($logo_rel) !== ''): ?>
|
||||||
<?= img_tag($logo_rel, ['loading' => 'eager', 'decoding' => 'async', 'alt' => 'Logo ' . (current_gym()['name'] ?? 'FitMe 3070'), 'style' => 'width: 150px; height: auto;']) ?>
|
<?= img_tag($logo_rel, ['loading' => 'eager', 'decoding' => 'async', 'alt' => 'Logo ' . (current_gym()['name'] ?? 'FitMe 3070')]) ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<img loading="eager" decoding="async" alt="Logo <?= htmlspecialchars(current_gym()['name'] ?? 'FitMe 3070') ?>" src="<?= htmlspecialchars($logo) ?>" <?= $logo_dims ?> style="width: 150px; height: auto;">
|
<img loading="eager" decoding="async" alt="Logo <?= htmlspecialchars(current_gym()['name'] ?? 'FitMe 3070') ?>" src="<?= htmlspecialchars($logo) ?>" <?= $logo_dims ?>>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</a>
|
</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button>
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button>
|
||||||
@@ -89,6 +92,14 @@ $logo_dims = svg_img_dims_attr(dirname(__DIR__, 2) . '/' . $logo_rel);
|
|||||||
// querySelector('#equipa') returns null, `sections` stays empty, and neither
|
// querySelector('#equipa') returns null, `sections` stays empty, and neither
|
||||||
// the smooth-scroll nor the scroll-spy (active nav link) ever bind.
|
// the smooth-scroll nor the scroll-spy (active nav link) ever bind.
|
||||||
function init() {
|
function init() {
|
||||||
|
/* ── Centred logo: docks into the bar once the page leaves the top ───── */
|
||||||
|
var header = document.querySelector('.header-section.has-center-logo');
|
||||||
|
if (header) {
|
||||||
|
var dock = function() { header.classList.toggle('is-top', window.scrollY < 40); };
|
||||||
|
window.addEventListener('scroll', dock, { passive: true });
|
||||||
|
dock();
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Eased smooth-scroll helper ──────────────────────────────────────── */
|
/* ── Eased smooth-scroll helper ──────────────────────────────────────── */
|
||||||
function smoothScrollTo(targetEl, duration) {
|
function smoothScrollTo(targetEl, duration) {
|
||||||
var start = window.scrollY;
|
var start = window.scrollY;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// One-page site: Home + Equipa + Modalidades + Horário + Contactos.
|
// One-page site: Home + Equipa + Modalidades + Horário + Contactos.
|
||||||
// CrossFit is a separate page (site/crossfit.php).
|
// CrossFit is a separate page (site/crossfit.php).
|
||||||
$current_uri_2 = '';
|
$current_uri_2 = '';
|
||||||
|
$nav_center_logo = true; // big centred logo over the hero, docks left on scroll (navbar.php)
|
||||||
|
|
||||||
// No gym in the URL (/, /home, old links): send people to a gym page. With a
|
// No gym in the URL (/, /home, old links): send people to a gym page. With a
|
||||||
// single published gym that is a 301 to it (query string kept, e.g.
|
// single published gym that is a 301 to it (query string kept, e.g.
|
||||||
|
|||||||
Reference in new issue
Block a user