release: promote beta to main (gyms, brand colours, JPEG XL, SEO per gym) #3
+58
-34
@@ -354,20 +354,23 @@ section[id] {
|
|||||||
color: var(--fitme-accent);
|
color: var(--fitme-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── 3D "pushable" neon button ─────────────────────────────────────────────────
|
/* ── 3D "pushable" neon button (seen at an angle) ──────────────────────────────
|
||||||
The element itself is the face. On hover it lifts straight up by --depth and
|
The element itself is the face. On hover it lifts toward the viewer — up by
|
||||||
a ::before strip, hanging off the face's bottom edge, grows to fill the gap:
|
--depth and left by --depth-x — and two pseudo-elements grow to fill the gap:
|
||||||
that strip is the extruded wall, lit in the brand colour with a neon glow
|
::before is the bottom wall, ::after the right wall. Each is a parallelogram
|
||||||
(darker at both ends like a rounded edge). Only transform / opacity animate
|
(clip-path) joining the face's edge to where the face used to be, so the
|
||||||
(compositor-only). Lift springs (overshoot curve), release is slow, press is
|
solid reads as an extruded block viewed from the right. Walls are lit in the
|
||||||
instant — same feel as a physical key. Colours come from --fitme-accent, so
|
brand colour with a neon glow; the right one is a shade darker (light comes
|
||||||
each gym glows in its own colour. */
|
from the top-left). Only transform animates (compositor-only): lift springs
|
||||||
|
(overshoot curve), release is slow, press is instant. Colours come from
|
||||||
|
--fitme-accent, so each gym glows in its own colour. */
|
||||||
:where(.site-btn, .gym-switch-btn) { position: relative; }
|
:where(.site-btn, .gym-switch-btn) { position: relative; }
|
||||||
|
|
||||||
.site-btn,
|
.site-btn,
|
||||||
.gym-switch-btn {
|
.gym-switch-btn {
|
||||||
--depth: 5px;
|
--depth: 5px; /* lift (and bottom wall height) */
|
||||||
--bw: 0px; /* the element's own border, so the wall starts below it */
|
--depth-x: 4px; /* shift to the left (and right wall width) */
|
||||||
|
--bw: 0px; /* the element's own border, so the walls start outside it */
|
||||||
--wall-hi: color-mix(in srgb, var(--fitme-accent) 70%, #fff);
|
--wall-hi: color-mix(in srgb, var(--fitme-accent) 70%, #fff);
|
||||||
--wall: var(--fitme-accent);
|
--wall: var(--fitme-accent);
|
||||||
--wall-lo: color-mix(in srgb, var(--fitme-accent) 45%, #000);
|
--wall-lo: color-mix(in srgb, var(--fitme-accent) 45%, #000);
|
||||||
@@ -376,30 +379,51 @@ section[id] {
|
|||||||
.site-btn.sb-ghost { --bw: 2px; }
|
.site-btn.sb-ghost { --bw: 2px; }
|
||||||
|
|
||||||
.site-btn::before,
|
.site-btn::before,
|
||||||
.gym-switch-btn::before {
|
.site-btn::after,
|
||||||
|
.gym-switch-btn::before,
|
||||||
|
.gym-switch-btn::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: calc(100% + var(--bw));
|
|
||||||
height: var(--depth);
|
|
||||||
border-radius: 0 0 var(--fitme-radius) var(--fitme-radius);
|
|
||||||
background: linear-gradient(to right, var(--wall-lo) 0%, var(--wall) 10%, var(--wall-hi) 50%, var(--wall) 90%, var(--wall-lo) 100%);
|
|
||||||
box-shadow: 0 2px 14px 1px rgba(var(--fitme-accent-rgb), .6);
|
|
||||||
transform: scaleY(0);
|
|
||||||
transform-origin: top;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
transform-origin: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bottom wall */
|
||||||
|
.site-btn::before,
|
||||||
|
.gym-switch-btn::before {
|
||||||
|
left: calc(var(--bw) * -1);
|
||||||
|
top: calc(100% + var(--bw));
|
||||||
|
width: calc(100% + var(--bw) * 2 + var(--depth-x));
|
||||||
|
height: var(--depth);
|
||||||
|
background: linear-gradient(to right, var(--wall-lo) 0%, var(--wall) 12%, var(--wall-hi) 50%, var(--wall) 88%, var(--wall-lo) 100%);
|
||||||
|
clip-path: polygon(0 0, calc(100% - var(--depth-x)) 0, 100% 100%, var(--depth-x) 100%);
|
||||||
|
transform: scaleY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* right wall */
|
||||||
|
.site-btn::after,
|
||||||
|
.gym-switch-btn::after {
|
||||||
|
left: calc(100% + var(--bw));
|
||||||
|
top: calc(var(--bw) * -1);
|
||||||
|
width: var(--depth-x);
|
||||||
|
height: calc(100% + var(--bw) * 2 + var(--depth));
|
||||||
|
background: linear-gradient(to bottom, var(--wall) 0%, var(--wall-lo) 100%);
|
||||||
|
clip-path: polygon(0 0, 100% var(--depth), 100% 100%, 0 calc(100% - var(--depth)));
|
||||||
|
transform: scaleX(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
|
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
|
||||||
.site-btn,
|
.site-btn,
|
||||||
.gym-switch-btn {
|
.gym-switch-btn {
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
|
/* the face colour fades slowly so the change to near-black never "pops" */
|
||||||
transition: transform 600ms cubic-bezier(.3, .7, .4, 1), box-shadow 600ms cubic-bezier(.3, .7, .4, 1),
|
transition: transform 600ms cubic-bezier(.3, .7, .4, 1), box-shadow 600ms cubic-bezier(.3, .7, .4, 1),
|
||||||
background var(--fitme-transition), color var(--fitme-transition);
|
background-color 450ms ease, border-color 450ms ease, color 450ms ease;
|
||||||
}
|
}
|
||||||
.site-btn::before,
|
.site-btn::before,
|
||||||
.gym-switch-btn::before {
|
.site-btn::after,
|
||||||
|
.gym-switch-btn::before,
|
||||||
|
.gym-switch-btn::after {
|
||||||
transition: transform 600ms cubic-bezier(.3, .7, .4, 1);
|
transition: transform 600ms cubic-bezier(.3, .7, .4, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,29 +431,29 @@ section[id] {
|
|||||||
.site-btn:focus-visible,
|
.site-btn:focus-visible,
|
||||||
.gym-switch-btn:hover,
|
.gym-switch-btn:hover,
|
||||||
.gym-switch-btn:focus-visible {
|
.gym-switch-btn:focus-visible {
|
||||||
transform: translateY(calc(var(--depth) * -1));
|
transform: translate(calc(var(--depth-x) * -1), calc(var(--depth) * -1));
|
||||||
box-shadow: 0 0 18px 2px rgba(var(--fitme-accent-rgb), .35);
|
box-shadow: 0 0 18px 2px rgba(var(--fitme-accent-rgb), .35);
|
||||||
transition-duration: 250ms, 250ms, var(--fitme-transition), var(--fitme-transition);
|
transition-duration: 250ms, 250ms, 450ms, 450ms, 450ms;
|
||||||
transition-timing-function: cubic-bezier(.3, .7, .4, 1.5);
|
transition-timing-function: cubic-bezier(.3, .7, .4, 1.5), cubic-bezier(.3, .7, .4, 1.5), ease, ease, ease;
|
||||||
}
|
}
|
||||||
.site-btn:hover::before,
|
.site-btn:hover::before,
|
||||||
.site-btn:focus-visible::before,
|
.site-btn:focus-visible::before,
|
||||||
.gym-switch-btn:hover::before,
|
.gym-switch-btn:hover::before,
|
||||||
.gym-switch-btn:focus-visible::before {
|
.gym-switch-btn:focus-visible::before { transform: scaleY(1); transition: transform 250ms cubic-bezier(.3, .7, .4, 1.5); }
|
||||||
transform: scaleY(1);
|
.site-btn:hover::after,
|
||||||
transition: transform 250ms cubic-bezier(.3, .7, .4, 1.5);
|
.site-btn:focus-visible::after,
|
||||||
}
|
.gym-switch-btn:hover::after,
|
||||||
|
.gym-switch-btn:focus-visible::after { transform: scaleX(1); transition: transform 250ms cubic-bezier(.3, .7, .4, 1.5); }
|
||||||
|
|
||||||
.site-btn:active,
|
.site-btn:active,
|
||||||
.gym-switch-btn:active {
|
.gym-switch-btn:active {
|
||||||
transform: translateY(-1px);
|
transform: translate(-1px, -1px);
|
||||||
transition-duration: 34ms;
|
transition-duration: 34ms;
|
||||||
}
|
}
|
||||||
.site-btn:active::before,
|
.site-btn:active::before,
|
||||||
.gym-switch-btn:active::before {
|
.gym-switch-btn:active::before { transform: scaleY(.2); transition-duration: 34ms; }
|
||||||
transform: scaleY(.2);
|
.site-btn:active::after,
|
||||||
transition-duration: 34ms;
|
.gym-switch-btn:active::after { transform: scaleX(.25); transition-duration: 34ms; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 —
|
||||||
|
|||||||
Reference in new issue
Block a user