diff --git a/site/assets/css/style.css b/site/assets/css/style.css index f4b2932..41e2d11 100644 --- a/site/assets/css/style.css +++ b/site/assets/css/style.css @@ -354,20 +354,23 @@ section[id] { color: var(--fitme-accent); } -/* ── 3D "pushable" neon button ───────────────────────────────────────────────── - The element itself is the face. On hover it lifts straight up by --depth and - a ::before strip, hanging off the face's bottom edge, grows to fill the gap: - that strip is the extruded wall, lit in the brand colour with a neon glow - (darker at both ends like a rounded edge). Only transform / opacity animate - (compositor-only). Lift springs (overshoot curve), release is slow, press is - instant — same feel as a physical key. Colours come from --fitme-accent, so - each gym glows in its own colour. */ +/* ── 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, so the + solid reads as an extruded block viewed from the right. Walls are lit in the + brand colour with a neon glow; the right one is a shade darker (light comes + 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; } .site-btn, .gym-switch-btn { - --depth: 5px; - --bw: 0px; /* the element's own border, so the wall starts below it */ + --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 */ --wall-hi: color-mix(in srgb, var(--fitme-accent) 70%, #fff); --wall: var(--fitme-accent); --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::before, -.gym-switch-btn::before { +.site-btn::after, +.gym-switch-btn::before, +.gym-switch-btn::after { content: ""; 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; + 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) { .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 var(--fitme-transition), color var(--fitme-transition); + background-color 450ms ease, border-color 450ms ease, color 450ms ease; } .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); } @@ -407,29 +431,29 @@ section[id] { .site-btn:focus-visible, .gym-switch-btn:hover, .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); - transition-duration: 250ms, 250ms, var(--fitme-transition), var(--fitme-transition); - transition-timing-function: cubic-bezier(.3, .7, .4, 1.5); + transition-duration: 250ms, 250ms, 450ms, 450ms, 450ms; + 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: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); - } + .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); } .site-btn:active, .gym-switch-btn:active { - transform: translateY(-1px); + transform: translate(-1px, -1px); transition-duration: 34ms; } .site-btn:active::before, - .gym-switch-btn:active::before { - transform: scaleY(.2); - transition-duration: 34ms; - } + .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; } } /* Hover: white text on an almost-black face keeping ~10% of the brand colour —