revert(site): drop the 3D neon button/photo-frame hover effect
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f28b2b8482
commit
8e889adeb9
1 file changed
-256
@@ -354,262 +354,6 @@ section[id] {
|
||||
color: var(--fitme-accent);
|
||||
}
|
||||
|
||||
/* ── 3D "pushable" neon button (seen at an angle) ──────────────────────────────
|
||||
The element itself is the face. On hover it lifts toward the viewer — up by
|
||||
--depth and left by --depth-x — and two pseudo-elements grow to fill the gap:
|
||||
::before is the bottom wall, ::after the right wall. Each is a parallelogram
|
||||
(clip-path) joining the face's edge to where the face used to be; they share
|
||||
the diagonal from the face's corner, so the join has no gap and no overlap.
|
||||
|
||||
Light model (key light top-left, the walls are the neon tubes):
|
||||
- Glow lives on the walls and spills onto the page under/around them. The
|
||||
halo is an outer box-shadow offset toward the walls (never painted inside
|
||||
the face, no drop-shadow, so no ghost copy of the text), blooming in with
|
||||
the lift and tightening on press.
|
||||
- Walls: hot near-white core in the middle of their length, saturated brand
|
||||
colour on the falloff, darkest at the ends; across their thickness bright
|
||||
where they meet the face, darker at the far edge. The right wall is one
|
||||
step darker than the bottom; both reach the darkest value (ambient
|
||||
occlusion) where they meet in the corner.
|
||||
- Contact shadow: a tight dark line just past the walls' far edges.
|
||||
- Face: only a faint rim light near the edges, a thin specular line on the
|
||||
top-left edge, slightly darker toward the bottom/right. Centre untouched.
|
||||
Colours derive from --fitme-accent with color-mix(), so any gym colour works. */
|
||||
:where(.site-btn, .gym-switch-btn) { position: relative; }
|
||||
|
||||
.site-btn,
|
||||
.gym-switch-btn,
|
||||
.trainer-item .trainer-pic {
|
||||
--wall-hi: color-mix(in srgb, var(--fitme-accent) 40%, #fff); /* hot core of the tube */
|
||||
--wall: var(--fitme-accent);
|
||||
--wall-lo: color-mix(in srgb, var(--fitme-accent) 60%, #000);
|
||||
--wall-ao: color-mix(in srgb, var(--fitme-accent) 30%, #000); /* corner / far ends */
|
||||
/* bottom wall: across thickness (bright at the face, dark far edge) over along length */
|
||||
--wall-bottom:
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .28) 0%, rgba(255, 255, 255, 0) 40%, rgba(0, 0, 0, .4) 100%),
|
||||
linear-gradient(to right, var(--wall-lo) 0%, var(--wall) 18%, var(--wall-hi) 48%, var(--wall) 78%, var(--wall-ao) 100%);
|
||||
/* right wall: one step darker, ends in the same --wall-ao at the corner */
|
||||
--wall-right:
|
||||
linear-gradient(to right, rgba(255, 255, 255, .14) 0%, rgba(0, 0, 0, .12) 45%, rgba(0, 0, 0, .5) 100%),
|
||||
linear-gradient(to bottom, var(--wall-lo) 0%, var(--wall) 22%, color-mix(in srgb, var(--wall-hi) 60%, var(--wall)) 50%, var(--wall-lo) 82%, var(--wall-ao) 100%);
|
||||
/* halo stacks (outer only): contact shadow, tight bloom, wide ambient spill */
|
||||
--neon-on:
|
||||
calc(var(--depth-x) + 1px) calc(var(--depth) + 1px) 2px rgba(0, 0, 0, .45),
|
||||
calc(var(--depth-x) * .75) var(--depth) 7px 0 rgba(var(--fitme-accent-rgb), .5),
|
||||
var(--depth-x) calc(var(--depth) * 1.6) 24px 2px rgba(var(--fitme-accent-rgb), .24);
|
||||
--neon-dim:
|
||||
calc(var(--depth-x) + 1px) calc(var(--depth) + 1px) 2px rgba(0, 0, 0, .45),
|
||||
calc(var(--depth-x) * .75) var(--depth) 6px 0 rgba(var(--fitme-accent-rgb), .25),
|
||||
var(--depth-x) calc(var(--depth) * 1.6) 20px 0 rgba(var(--fitme-accent-rgb), .1);
|
||||
--neon-off:
|
||||
calc(var(--depth-x) + 1px) calc(var(--depth) + 1px) 2px rgba(0, 0, 0, .45),
|
||||
calc(var(--depth-x) * .75) var(--depth) 4px 0 rgba(var(--fitme-accent-rgb), .08),
|
||||
var(--depth-x) calc(var(--depth) * 1.6) 16px 0 rgba(var(--fitme-accent-rgb), 0);
|
||||
/* pressed: wall compressed to ~1px, glow pulled in close */
|
||||
--neon-press:
|
||||
1px 1px 1px rgba(0, 0, 0, .5),
|
||||
1px 1px 4px 0 rgba(var(--fitme-accent-rgb), .55),
|
||||
1px 2px 12px 0 rgba(var(--fitme-accent-rgb), .2);
|
||||
/* face shading (inset): specular top-left, lit seam bottom-right, shade, faint rim */
|
||||
--face-light:
|
||||
inset 1px 1px 0 color-mix(in srgb, var(--wall-hi) 55%, transparent),
|
||||
inset -1px -1px 0 rgba(var(--fitme-accent-rgb), .5),
|
||||
inset -3px -4px 8px -2px rgba(0, 0, 0, .55),
|
||||
inset 0 0 7px -3px rgba(var(--fitme-accent-rgb), .45);
|
||||
}
|
||||
|
||||
.site-btn,
|
||||
.gym-switch-btn {
|
||||
--depth: 5px; /* lift (and bottom wall height) */
|
||||
--depth-x: 4px; /* shift to the left (and right wall width) */
|
||||
--bw: 0px; /* the element's own border, so the walls start outside it */
|
||||
--neon-face-on: var(--face-light), var(--neon-on);
|
||||
--neon-face-dim: var(--face-light), var(--neon-dim);
|
||||
--neon-face-off: var(--face-light), var(--neon-off);
|
||||
}
|
||||
.site-btn.sb-line,
|
||||
.site-btn.sb-ghost { --bw: 2px; }
|
||||
|
||||
.site-btn::before,
|
||||
.site-btn::after,
|
||||
.gym-switch-btn::before,
|
||||
.gym-switch-btn::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
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: var(--wall-bottom);
|
||||
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: var(--wall-right);
|
||||
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) {
|
||||
.site-btn,
|
||||
.gym-switch-btn {
|
||||
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),
|
||||
background-color 450ms ease, border-color 450ms ease, color 450ms ease;
|
||||
}
|
||||
.site-btn::before,
|
||||
.site-btn::after,
|
||||
.gym-switch-btn::before,
|
||||
.gym-switch-btn::after {
|
||||
transition: transform 600ms cubic-bezier(.3, .7, .4, 1);
|
||||
}
|
||||
|
||||
.site-btn:hover,
|
||||
.site-btn:focus-visible,
|
||||
.gym-switch-btn:hover,
|
||||
.gym-switch-btn:focus-visible {
|
||||
transform: translate(calc(var(--depth-x) * -1), calc(var(--depth) * -1));
|
||||
box-shadow: var(--neon-face-on);
|
||||
/* lift springs fast; the bloom eases in a little slower so it grows with the lift */
|
||||
transition-duration: 250ms, 380ms, 450ms, 450ms, 450ms;
|
||||
transition-timing-function: cubic-bezier(.3, .7, .4, 1.5), ease-out, ease, ease, ease;
|
||||
}
|
||||
.site-btn:hover::before,
|
||||
.site-btn:focus-visible::before,
|
||||
.gym-switch-btn:hover::before,
|
||||
.gym-switch-btn:focus-visible::before { transform: scaleY(1); transition: transform 250ms cubic-bezier(.3, .7, .4, 1.5); }
|
||||
.site-btn:hover::after,
|
||||
.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); }
|
||||
|
||||
/* Neon blink: after a moment of hovering, one short stutter — like a tube
|
||||
that isn't quite seated — then steady. Walls (opacity) and halo
|
||||
(box-shadow) dim on the same keyframe times. */
|
||||
.site-btn:hover,
|
||||
.site-btn:focus-visible,
|
||||
.gym-switch-btn:hover,
|
||||
.gym-switch-btn:focus-visible { animation: neon-flicker-glow 600ms linear 1.4s 1; }
|
||||
.site-btn:hover::before,
|
||||
.site-btn:hover::after,
|
||||
.site-btn:focus-visible::before,
|
||||
.site-btn:focus-visible::after,
|
||||
.gym-switch-btn:hover::before,
|
||||
.gym-switch-btn:hover::after,
|
||||
.gym-switch-btn:focus-visible::before,
|
||||
.gym-switch-btn:focus-visible::after { animation: neon-flicker-tube 600ms linear 1.4s 1; }
|
||||
|
||||
.site-btn:active,
|
||||
.gym-switch-btn:active {
|
||||
transform: translate(-1px, -1px);
|
||||
box-shadow: var(--face-light), var(--neon-press);
|
||||
animation: none;
|
||||
transition-duration: 34ms;
|
||||
}
|
||||
.site-btn:active::before,
|
||||
.gym-switch-btn:active::before { transform: scaleY(.2); transition-duration: 34ms; }
|
||||
.site-btn:active::after,
|
||||
.gym-switch-btn:active::after { transform: scaleX(.25); transition-duration: 34ms; }
|
||||
}
|
||||
|
||||
@keyframes neon-flicker-tube {
|
||||
0%, 30%, 65%, 100% { opacity: 1; }
|
||||
15% { opacity: .3; }
|
||||
50% { opacity: .55; }
|
||||
}
|
||||
@keyframes neon-flicker-glow {
|
||||
0%, 30%, 65%, 100% { box-shadow: var(--neon-face-on); }
|
||||
15% { box-shadow: var(--neon-face-off); }
|
||||
50% { box-shadow: var(--neon-face-dim); }
|
||||
}
|
||||
|
||||
/* ── Team photo frames: the same neon extrusion ────────────────────────────────
|
||||
.trainer-pic is the face. Its ::before draws the L-shaped wall (bottom + right,
|
||||
one clipped polygon, the same wall gradients); ::after stays the existing
|
||||
gloss overlay and also carries the face shading. The halo is the frame's
|
||||
outer box-shadow only (no inset there, the photo covers it). The frame no
|
||||
longer clips its children (overflow:hidden would cut the wall). */
|
||||
.trainer-item .trainer-pic {
|
||||
--depth: 5px;
|
||||
--depth-x: 4px;
|
||||
--bw: 4px; /* the frame's own border */
|
||||
--neon-face-on: var(--neon-on);
|
||||
--neon-face-dim: var(--neon-dim);
|
||||
--neon-face-off: var(--neon-off);
|
||||
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;
|
||||
/* the two gradient pairs, each sized to its wall's box (bottom strip, right strip) */
|
||||
background:
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .28) 0%, rgba(255, 255, 255, 0) 40%, rgba(0, 0, 0, .4) 100%)
|
||||
0 100% / calc(100% - var(--depth-x)) var(--depth) no-repeat,
|
||||
linear-gradient(to right, var(--wall-lo) 0%, var(--wall) 18%, var(--wall-hi) 48%, var(--wall) 78%, var(--wall-ao) 100%)
|
||||
0 100% / calc(100% - var(--depth-x)) var(--depth) no-repeat,
|
||||
linear-gradient(to right, rgba(255, 255, 255, .14) 0%, rgba(0, 0, 0, .12) 45%, rgba(0, 0, 0, .5) 100%)
|
||||
100% 0 / var(--depth-x) 100% no-repeat,
|
||||
linear-gradient(to bottom, var(--wall-lo) 0%, var(--wall) 22%, color-mix(in srgb, var(--wall-hi) 60%, var(--wall)) 50%, var(--wall-lo) 82%, var(--wall-ao) 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: var(--neon-face-on);
|
||||
}
|
||||
.trainer-item .trainer-pic:hover::before { opacity: 1; }
|
||||
.trainer-item .trainer-pic:hover::after { box-shadow: var(--face-light); }
|
||||
|
||||
@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 .38s ease-out; }
|
||||
.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
|
||||
(white on it is >= 15:1 for any brand colour, even pure white or black).
|
||||
The lettering gets a dark backing under the neon text-shadow so very light
|
||||
brand colours never wash the letter edges out. The dark and ghost variants
|
||||
keep their own backgrounds. */
|
||||
.site-btn:not(.sb-dark):not(.sb-line):not(.sb-ghost):hover,
|
||||
.site-btn:not(.sb-dark):not(.sb-line):not(.sb-ghost):focus-visible,
|
||||
.gym-switch-btn:hover,
|
||||
.gym-switch-btn:focus-visible {
|
||||
background: color-mix(in srgb, var(--fitme-accent) 10%, #000);
|
||||
border-color: color-mix(in srgb, var(--fitme-accent) 10%, #000);
|
||||
color: #fff;
|
||||
text-shadow: 0 0 1px rgba(0, 0, 0, .8), 0 0 7px rgba(var(--fitme-accent-rgb), .75); /* neon lettering */
|
||||
}
|
||||
.site-btn.sb-dark:hover,
|
||||
.site-btn.sb-line:hover { color: #fff; }
|
||||
|
||||
/* ── Bootstrap Nav Overrides ───────────────────────────────────────────────── */
|
||||
.nav-link {
|
||||
font-weight: 700;
|
||||
|
||||
Reference in new issue
Block a user