From 4b99991c11aa99483c5648f2d973cd8ef22d1282 Mon Sep 17 00:00:00 2001 From: andre Date: Tue, 13 Oct 2026 18:26:43 +0100 Subject: [PATCH] style(site): neon extrusion on the team photo frames Co-Authored-By: Claude Sonnet 5.5 --- site/assets/css/style.css | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/site/assets/css/style.css b/site/assets/css/style.css index 3d47e44..ff16a10 100644 --- a/site/assets/css/style.css +++ b/site/assets/css/style.css @@ -490,6 +490,58 @@ section[id] { 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 — the bright neon faces around it then stand out against it. The dark and ghost variants keep their own backgrounds. */