release: promote beta to main (gyms, brand colours, JPEG XL, SEO per gym) #3

Merged
andre merged 74 commits from beta into main 2026-10-26 19:47:48 +00:00
Showing only changes of commit 4b99991c11 - Show all commits
+52
View File
@@ -490,6 +490,58 @@ section[id] {
50% { filter: drop-shadow(0 0 2px rgba(var(--fitme-accent-rgb), .45)); } 50% { filter: drop-shadow(0 0 2px rgba(var(--fitme-accent-rgb), .45)); }
} }
/* ── Team photo frames: the same neon extrusion ────────────────────────────────
.trainer-pic is the face. Its ::before draws the L-shaped wall (bottom + right,
one clipped polygon, two gradients); ::after stays the existing gloss overlay
and also carries the inner glow. The frame no longer clips its children
(overflow:hidden would cut the wall), the photo fills the padding box anyway. */
.trainer-item .trainer-pic {
--depth: 5px;
--depth-x: 4px;
--bw: 4px; /* the frame's own border */
--wall-hi: color-mix(in srgb, var(--fitme-accent) 45%, #fff);
--wall: var(--fitme-accent);
--wall-lo: color-mix(in srgb, var(--fitme-accent) 65%, #000);
overflow: visible;
}
.trainer-item .trainer-pic::before {
content: "";
position: absolute;
left: calc(var(--bw) * -1);
top: calc(var(--bw) * -1);
width: calc(100% + var(--bw) * 2 + var(--depth-x));
height: calc(100% + var(--bw) * 2 + var(--depth));
z-index: -1;
pointer-events: none;
opacity: 0;
background:
linear-gradient(to right, var(--wall-lo) 0%, var(--wall) 1%, var(--wall-hi) 50%, var(--wall) 99%, var(--wall-lo) 100%)
0 100% / calc(100% - var(--depth-x)) var(--depth) no-repeat,
linear-gradient(to bottom, var(--wall) 0%, var(--wall-lo) 100%)
100% 0 / var(--depth-x) 100% no-repeat;
clip-path: polygon(0 calc(100% - var(--depth)), calc(100% - var(--depth-x)) calc(100% - var(--depth)),
calc(100% - var(--depth-x)) 0, 100% var(--depth), 100% 100%, var(--depth-x) 100%);
transition: opacity .25s ease;
}
.trainer-item .trainer-pic:hover,
#powerRotation>div:nth-child(even) .trainer-pic:hover {
transform: rotate(0deg) translate(calc(var(--depth-x) * -1), calc(var(--depth) * -1)) scale(1.03);
box-shadow: 0 0 12px 1px rgba(var(--fitme-accent-rgb), .25);
filter: drop-shadow(0 0 5px rgba(var(--fitme-accent-rgb), .9)) drop-shadow(0 0 14px rgba(var(--fitme-accent-rgb), .55));
}
.trainer-item .trainer-pic:hover::before { opacity: 1; }
.trainer-item .trainer-pic:hover::after {
box-shadow: inset 0 0 14px 1px rgba(var(--fitme-accent-rgb), .4), inset 0 0 3px 0 rgba(var(--fitme-accent-rgb), .6);
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
.trainer-item .trainer-pic { transition: transform .25s cubic-bezier(.3, .7, .4, 1.5), box-shadow .45s ease, filter .45s ease; }
.trainer-item .trainer-pic:hover { animation: neon-flicker-glow 600ms linear 1.4s 1; }
.trainer-item .trainer-pic:hover::before { animation: neon-flicker-tube 600ms linear 1.4s 1; }
}
/* Hover: white text on an almost-black face keeping ~10% of the brand colour — /* Hover: white text on an almost-black face keeping ~10% of the brand colour —
the bright neon faces around it then stand out against it. The dark and the bright neon faces around it then stand out against it. The dark and
ghost variants keep their own backgrounds. */ ghost variants keep their own backgrounds. */