style(navbar): logo crossfade, match-head end, full-screen mobile menu, brand slash template

This commit is contained in:
andre committed 2026-10-26 11:53:44 +00:00
1 parent 2e8b6d20f6
commit 4b54a777b7
3 files changed
+131 -35

No files matched your search

+118 -24
View File
@@ -359,14 +359,30 @@ section[id] {
/* ── Bootstrap Nav Overrides ───────────────────────────────────────────────── */
.nav-link {
font-weight: 700;
font-size: .875rem;
letter-spacing: .02em;
color: var(--fitme-text);
margin: 0 .6rem !important;
transition: color var(--fitme-transition);
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. */
/* ── Brand slash (template) ──────────────────────────────────────────────────
The cut of the "in" box in the FitMe in logo: top-left and bottom-right
corners sliced off. Put class="fx-slash" on any element (or add a pseudo
element to this list) instead of writing the polygon again; --slash sets the
cut size. .fx-slash-start cuts the left side only (open to the right edge). */
:root { --slash: 4px; }
.fx-slash,
.nav-link::after,
.section-title.deco h2::after {
clip-path: polygon(var(--slash) 0, 100% 0, calc(100% - var(--slash)) 100%, 0 100%);
}
.fx-slash-start {
clip-path: polygon(var(--slash) 0, 100% 0, 100% 100%, 0 100%);
}
/* Underline: a short bar with the brand slash, tucked right under the text. */
.nav-link:after {
content: '';
position: absolute;
@@ -375,7 +391,6 @@ section[id] {
right: var(--bs-navbar-nav-link-padding-x, .5rem);
height: 4px;
background: var(--fitme-accent);
clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
transform: scaleX(0);
transform-origin: left;
transition: transform var(--fitme-transition);
@@ -402,8 +417,8 @@ section[id] {
text-transform: uppercase;
letter-spacing: .5px;
border: 2px solid var(--fitme-accent);
border-radius: var(--fitme-radius);
padding: 6px 14px !important;
--slash: 8px; /* shape: .fx-slash on the link (navbar.php) */
padding: 6px 16px !important;
transition: background-color .4s ease, color .4s ease, border-color .4s ease;
}
@@ -610,14 +625,15 @@ section[id] {
/* Bar layout. Desktop: the links are centred on the full bar width, the logo
sits out of flow at the left and the other-gym buttons out of flow at the
right, vertically centred on the whole header. On the home page
(.has-center-logo) the header starts taller with the logo bigger and centred
(.is-top); on scroll everything glides back (navbar.php toggles .is-top). */
(.has-center-logo) the header starts taller with a big centred copy of the
logo (.navbar-brand-hero, .is-top); on scroll the bar shrinks, the big logo
fades out and the left one fades in (navbar.php toggles .is-top). */
.header-section .navbar { padding: 0 0 0 1rem; }
.navbar-brand img {
width: 150px;
height: auto;
transition: width .5s cubic-bezier(.4, 0, .2, 1);
}
.navbar-brand-hero { display: none; }
@media (min-width: 992px) {
.header-section .navbar {
padding: 0;
@@ -630,31 +646,99 @@ section[id] {
top: 50%;
margin: 0;
transform: translate(0, -50%);
transition: left .5s cubic-bezier(.4, 0, .2, 1), top .5s cubic-bezier(.4, 0, .2, 1), transform .5s cubic-bezier(.4, 0, .2, 1);
}
.header-section .navbar-brand,
.navbar-brand-hero {
transition: opacity .45s ease, visibility .45s;
}
.has-center-logo .navbar-brand-hero {
display: block;
position: absolute;
z-index: 1;
left: 50%;
top: 12px;
transform: translateX(-50%);
opacity: 0;
visibility: hidden;
}
.navbar-brand-hero img { width: 180px; height: auto; }
.header-section .navbar-collapse {
min-height: 58px;
align-items: center;
}
.header-section .gym-switch {
position: absolute;
right: 1rem;
top: 50%;
transform: translateY(-50%);
padding: 0 !important;
}
.header-section .gym-switch { position: absolute; } /* the match head, below */
.header-section.is-top .navbar { padding-top: 62px; } /* room for the 180px logo */
.header-section.is-top .navbar-brand {
left: 50%;
top: 12px;
transform: translate(-50%, 0);
/* Match head: the right end of the bar is a dark block behind the other-gym
button, its left side cut on the same slash as the underlines, with an
accent strip on the cut and an ember glow just inside it (the bar is the
matchstick, this is the head). ::before = accent strip, ::after = head. */
.header-section .gym-switch {
--slash: 22px;
top: 0;
bottom: 0;
right: 0;
transform: none;
z-index: 1;
align-items: center;
padding: 0 .85rem 0 calc(var(--slash) + .85rem) !important;
}
.header-section.is-top .navbar-brand img { width: 180px; }
.header-section .gym-switch::before,
.header-section .gym-switch::after {
content: '';
position: absolute;
inset: 0;
z-index: -1;
pointer-events: none;
clip-path: polygon(var(--slash) 0, 100% 0, 100% 100%, 0 100%); /* .fx-slash-start */
}
.header-section .gym-switch::before { left: -5px; background: var(--fitme-accent); }
.header-section .gym-switch::after {
background:
radial-gradient(70% 90% at 10% 50%, rgba(var(--fitme-accent-rgb), .38), transparent 70%),
linear-gradient(180deg, #1b1b1f, #0b0b0d);
}
/* other-gym logos are drawn for a light bar: flip lightness, keep the hues */
.header-section .gym-switch .gym-switch-btn--logo .gym-switch-logo {
filter: url(#pt-noise) invert(1) hue-rotate(180deg) drop-shadow(0 1px 1px rgba(0, 0, 0, .4));
}
.header-section.is-top .navbar-brand { opacity: 0; visibility: hidden; }
.header-section.is-top .navbar-brand-hero { opacity: 1; visibility: visible; }
/* keep the centred hero content (event card) clear of the taller top bar */
.hero-section { padding-top: 120px; }
}
@media (prefers-reduced-motion: reduce) {
.header-section .navbar, .header-section .navbar-brand, .navbar-brand img { transition: none; }
.header-section .navbar, .header-section .navbar-brand, .navbar-brand-hero { transition: none; }
}
/* Mobile/tablet menu: the open collapse fills the screen below the bar, links
and gym buttons centred both ways, fading in and out. It is position:absolute
(top:100% of the .navbar), not fixed: the header's backdrop-filter makes the
header the containing block for fixed children anyway. Links shrink to their
text so the underline is only as wide as the word. */
@media (max-width: 991.98px) {
.header-section .navbar-collapse {
position: absolute;
top: 100%;
left: 0;
right: 0;
height: calc(100dvh - var(--nav-h, 60px)) !important;
overflow-y: auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1.5rem;
transition: opacity .3s ease;
}
.header-section .navbar-collapse:not(.show):not(.collapsing) { display: none; }
.header-section .navbar-collapse.collapsing { opacity: 0; transition: opacity .3s ease; }
.header-section .navbar-nav { align-items: center; gap: .25rem; }
.header-section .navbar-nav .nav-link { font-size: 1.25rem; margin: 0 !important; }
.header-section .navbar-nav .nav-link::after { left: 0; right: 0; } /* no side padding here */
.header-section .gym-switch { justify-content: center; }
}
@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) {
.header-section .navbar-collapse, .header-section .navbar-collapse.collapsing { transition: none; }
}
@media (prefers-reduced-motion: reduce) {
@@ -801,7 +885,15 @@ section[id] {
letter-spacing: -.5px;
}
/* Subtitle (gym hero_subtitle): same h1 but a much smaller, tracked-out line
so the title leads and this reads as its strapline. */
.hero-text h1 span {
display: block;
margin-top: .55em;
font-size: .42em;
font-weight: 800;
line-height: 1.3;
letter-spacing: .12em;
color: var(--fitme-accent);
}
@@ -2204,6 +2296,9 @@ h3.contact-title {
/* ── 992px–1199px ──────────────────────────────────────────────────────────── */
@media only screen and (min-width: 992px) and (max-width: 1199px) {
/* tighter link spacing so a long menu (3070) clears the logo and match head */
.header-section .navbar-nav { --bs-navbar-nav-link-padding-x: .35rem; }
.header-section .nav-link { margin: 0 .2rem !important; font-size: .8125rem; }
.header-right .hr-box {
display: none !important;
}
@@ -2588,8 +2683,7 @@ h3.contact-title {
transform: translateX(-50%);
width: 64px;
height: 4px;
background: var(--fitme-accent);
clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%); /* slashed ends, as .nav-link:after */
background: var(--fitme-accent); /* slashed ends: "Brand slash" template */
}
.section-subtitle {
+12 -10
View File
@@ -9,19 +9,21 @@ else
}
$logo = base_url($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).
$logo_alt = 'Logo ' . (current_gym()['name'] ?? 'FitMe 3070');
$logo_html = img_fallback_rel($logo_rel) !== ''
? img_tag($logo_rel, ['loading' => 'eager', 'decoding' => 'async', 'alt' => $logo_alt])
: '<img loading="eager" decoding="async" alt="' . htmlspecialchars($logo_alt) . '" src="' . htmlspecialchars($logo) . '" ' . $logo_dims . '>';
// Home page: a second, big copy of the logo shows centred over the hero
// (.is-top); on scroll it fades out and the normal left logo fades in
// (script below toggles .is-top, style.css "Bar layout").
$center_logo = !empty($nav_center_logo);
?>
<header class="header-section lazy<?= $center_logo ? ' has-center-logo is-top' : '' ?>">
<nav class="navbar navbar-expand-lg navbar-light">
<a class="navbar-brand" href="<?= htmlspecialchars(gym_url(current_gym())) ?>">
<?php if (img_fallback_rel($logo_rel) !== ''): ?>
<?= img_tag($logo_rel, ['loading' => 'eager', 'decoding' => 'async', 'alt' => 'Logo ' . (current_gym()['name'] ?? 'FitMe 3070')]) ?>
<?php else: ?>
<img loading="eager" decoding="async" alt="Logo <?= htmlspecialchars(current_gym()['name'] ?? 'FitMe 3070') ?>" src="<?= htmlspecialchars($logo) ?>" <?= $logo_dims ?>>
<?php endif; ?>
</a>
<a class="navbar-brand" href="<?= htmlspecialchars(gym_url(current_gym())) ?>"><?= $logo_html ?></a>
<?php if ($center_logo): ?>
<a class="navbar-brand-hero" href="<?= htmlspecialchars(gym_url(current_gym())) ?>" aria-hidden="true" tabindex="-1"><?= $logo_html ?></a>
<?php endif; ?>
<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>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mx-auto ">
@@ -40,7 +42,7 @@ $center_logo = !empty($nav_center_logo);
?>
<li class="nav-item <?= $is_active ? 'active' : '' ?> main-menu-li" >
<?php if ($is_crossfit): ?>
<a class="nav-link crossfit-nav-link" href="<?= htmlspecialchars($n) ?>"<?= $is_active ? ' aria-current="page"' : '' ?>>
<a class="nav-link crossfit-nav-link fx-slash" href="<?= htmlspecialchars($n) ?>"<?= $is_active ? ' aria-current="page"' : '' ?>>
<?= $key ?>
</a>
<?php elseif ($is_anchor): ?>