Bouton style iPod Silver — aluminium anodisé brossé, surface polycarbonate laiteux, reflet parabolique, tilt 3D suivi de souris et inset physique réaliste au clic.
Déplace la souris sur le bouton pour le tilt 3D et le reflet spéculaire. Clique pour l'inset réaliste.
<div class="scene">
<div class="push-wrap">
<button class="lux-push" id="luxPush" type="button" aria-label="Push">
<span class="lux-push__halo"></span>
<span class="lux-push__rim"></span>
<span class="lux-push__bevel"></span>
<span class="lux-push__surface">
<span class="lux-push__specular"></span>
<span class="lux-push__gloss"></span>
<span class="lux-push__sheen"></span>
<span class="lux-push__undershine"></span>
<span class="lux-push__grain"></span>
<span class="lux-push__inner-rim"></span>
<span class="lux-push__label">Push</span>
</span>
</button>
</div>
</div>
:root{
--mx: 50%;
--my: 24%;
--rx: 0deg;
--ry: 0deg;
}
.scene { position: relative; isolation: isolate; }
.push-wrap {
position: relative;
display: grid;
place-items: center;
perspective: 1200px;
}
/* Ombre portée */
.push-wrap::before {
content: "";
position: absolute;
left: 50%; top: calc(100% - 4px);
width: 85%; height: 44px;
transform: translateX(-50%);
border-radius: 999px;
background: radial-gradient(ellipse at center,
rgba(100,90,80,.38) 0%, rgba(100,90,80,.18) 38%,
rgba(100,90,80,.05) 64%, rgba(100,90,80,0) 80%);
filter: blur(12px); z-index: 0;
transition: transform .1s ease, filter .12s ease, opacity .1s ease;
}
.push-wrap:has(.lux-push:active)::before {
transform: translateX(-50%) scaleX(.70) scaleY(.36);
filter: blur(6px); opacity: .55;
}
.lux-push {
all: unset;
position: relative; display: block;
width: min(360px, 88vw);
aspect-ratio: 2.95 / 1;
border-radius: 999px;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
z-index: 2;
transform: rotateX(var(--rx)) rotateY(var(--ry));
transform-style: preserve-3d;
transition: transform .22s cubic-bezier(.22,1,.36,1), filter .22s ease;
filter:
drop-shadow(0 12px 20px rgba(80,70,60,.22))
drop-shadow(0 4px 8px rgba(80,70,60,.14));
}
.push-wrap:hover .lux-push {
filter:
drop-shadow(0 16px 26px rgba(80,70,60,.28))
drop-shadow(0 5px 10px rgba(80,70,60,.16));
}
.lux-push:active {
filter:
drop-shadow(0 3px 5px rgba(80,70,60,.18))
drop-shadow(0 1px 3px rgba(80,70,60,.12)) !important;
transition-duration: .08s;
}
.lux-push > span {
position: absolute; inset: 0;
border-radius: inherit; pointer-events: none;
}
/* Anneau aluminium brossé */
.lux-push__rim {
background: linear-gradient(175deg,
#ffffff 0%,
rgba(250,250,248,1) 2%,
rgba(225,224,220,1) 6%,
rgba(195,193,188,1) 14%,
rgba(170,168,163,1) 24%,
rgba(148,146,141,1) 36%,
rgba(162,160,156,1) 48%,
rgba(180,178,174,1) 58%,
rgba(210,208,204,1) 70%,
rgba(238,236,232,1) 80%,
rgba(252,250,248,1) 88%,
rgba(175,172,166,1) 94%,
rgba(140,138,133,1) 100%);
box-shadow:
inset 0 1.5px 0 rgba(255,255,255,.90),
inset 0 -2px 3px rgba(80,76,70,.55),
inset 12px 0 18px rgba(255,255,255,.12),
inset -10px 0 18px rgba(80,76,70,.10),
0 18px 36px rgba(80,70,60,.25),
0 6px 14px rgba(80,70,60,.16),
0 2px 4px rgba(80,70,60,.18);
transition: box-shadow .1s ease;
}
.lux-push:active .lux-push__rim {
box-shadow:
inset 0 3px 2px rgba(100,96,90,.45),
inset 0 -1px 2px rgba(255,255,255,.45),
inset 12px 0 18px rgba(255,255,255,.08),
inset -10px 0 18px rgba(80,76,70,.12),
0 5px 10px rgba(80,70,60,.18),
0 2px 4px rgba(80,70,60,.14);
transition-duration: .08s;
}
/* Stries brossage radial */
.lux-push__rim::before {
content: ""; position: absolute; inset: 0; border-radius: inherit;
background: repeating-conic-gradient(
from 0deg at 50% 50%,
rgba(255,255,255,.030) 0deg .25deg,
rgba(255,255,255,0) .25deg 1.1deg);
opacity: .55; mix-blend-mode: overlay;
}
/* Reflets elliptiques haut/bas */
.lux-push__rim::after {
content: ""; position: absolute; inset: 0; border-radius: inherit;
background:
radial-gradient(ellipse 75% 38% at 50% 6%,
rgba(255,255,255,.32), transparent 70%),
radial-gradient(ellipse 60% 28% at 50% 94%,
rgba(255,255,255,.18), transparent 68%);
opacity: .88;
}
/* Bevel — rainure */
.lux-push__bevel {
inset: 7px;
background: linear-gradient(175deg,
rgba(160,158,154,.35) 0%, rgba(180,178,172,.15) 30%,
rgba(200,198,192,.08) 60%, rgba(130,128,124,.25) 100%);
box-shadow:
inset 0 1px 0 rgba(255,255,255,.35),
inset 0 -1px 1px rgba(80,76,70,.40),
inset 0 0 0 1px rgba(100,98,94,.18);
transition: box-shadow .1s ease;
}
.lux-push:active .lux-push__bevel {
box-shadow:
inset 0 2px 4px rgba(80,76,70,.55),
inset 0 -1px 2px rgba(255,255,255,.28),
inset 0 0 0 1px rgba(100,98,94,.22);
transition-duration: .08s;
}
/* Surface polycarbonate blanc */
.lux-push__surface {
inset: 13px; overflow: hidden;
background:
radial-gradient(ellipse 100% 160% at 50% -30%,
rgba(255,252,248,.60) 0%, rgba(255,255,255,0) 58%),
radial-gradient(ellipse 100% 140% at 50% 130%,
rgba(230,228,224,.40) 0%, rgba(255,255,255,0) 55%),
linear-gradient(175deg,
#f8f7f5 0%, #f2f0ee 25%, #eceae7 55%, #e4e2de 80%, #dedad6 100%);
box-shadow:
inset 0 1px 0 rgba(255,255,255,.95),
inset 0 -6px 14px rgba(120,115,108,.08),
inset 0 6px 16px rgba(255,255,255,.25),
inset 3px 0 5px rgba(255,255,255,.12),
inset -3px 0 6px rgba(120,115,108,.06);
transition: box-shadow .1s ease, background .1s ease;
}
/* Inset réaliste au press */
.lux-push:active .lux-push__surface {
background:
radial-gradient(ellipse 100% 160% at 50% 20%,
rgba(160,155,148,.28) 0%, rgba(255,255,255,0) 52%),
linear-gradient(175deg,
#dbd9d5 0%, #d5d3cf 25%, #cec9c5 58%, #c8c4c0 80%, #c2beba 100%);
box-shadow:
inset 0 8px 20px rgba(100,96,90,.28),
inset 0 3px 7px rgba(100,96,90,.20),
inset 6px 0 14px rgba(100,96,90,.14),
inset -6px 0 14px rgba(100,96,90,.14),
inset 0 0 28px rgba(80,76,70,.12),
inset 0 -2px 4px rgba(255,255,255,.22);
transition-duration: .08s;
}
/* Reflet mobile (suit la souris) */
.lux-push__specular {
inset: 0;
background: radial-gradient(
circle at var(--mx) var(--my),
rgba(255,255,255,.72) 0%,
rgba(255,255,255,.38) 7%,
rgba(255,255,255,.12) 15%,
rgba(255,255,255,0) 30%);
opacity: .80; transition: opacity .1s ease;
}
.lux-push:active .lux-push__specular { opacity: .18; transition-duration: .08s; }
/* Reflet parabolique fixe */
.lux-push__gloss {
inset: 0;
background:
radial-gradient(ellipse 82% 52% at 50% -6%,
rgba(255,255,255,.82) 0%, rgba(255,255,255,.45) 18%,
rgba(255,255,255,.12) 38%, rgba(255,255,255,0) 56%),
radial-gradient(ellipse 55% 32% at 50% 107%,
rgba(255,255,255,.28) 0%, rgba(255,255,255,0) 52%);
opacity: .88; transition: opacity .12s ease, transform .12s ease;
}
.lux-push:active .lux-push__gloss {
opacity: .22; transform: translateY(2px); transition-duration: .08s;
}
/* Sheen diagonal */
.lux-push__sheen {
inset: 0;
background: linear-gradient(108deg,
rgba(255,255,255,0) 0%,
rgba(255,255,255,.06) 26%,
rgba(255,255,255,.22) 38%,
rgba(255,255,255,.28) 43%,
rgba(255,255,255,.22) 48%,
rgba(255,255,255,.06) 58%,
rgba(255,255,255,0) 70%);
opacity: .45; transform: translateX(-8%);
transition: opacity .14s ease;
}
.push-wrap:hover .lux-push__sheen { opacity: .60; }
.lux-push:active .lux-push__sheen { opacity: .08; transition-duration: .08s; }
/* Grain plastique */
.lux-push__grain {
inset: 0; mix-blend-mode: multiply;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.2' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
background-size: 100px 100px; opacity: .06;
}
/* Contre-reflet bas */
.lux-push__undershine {
inset: auto 18% 4px 18%; height: 22%;
border-radius: 999px;
background: linear-gradient(0deg,
rgba(255,255,255,.55) 0%, rgba(255,255,255,0) 100%);
opacity: .60; transition: opacity .1s ease;
}
.lux-push:active .lux-push__undershine { opacity: .22; transition-duration: .08s; }
/* Rim intérieur */
.lux-push__inner-rim {
inset: 1px; border-radius: inherit;
box-shadow:
inset 0 1px 0 rgba(255,255,255,.75),
inset 0 -1px 0 rgba(120,115,108,.22);
opacity: .9; transition: box-shadow .1s ease;
}
.lux-push:active .lux-push__inner-rim {
box-shadow:
inset 0 1.5px 0 rgba(100,96,90,.38),
inset 0 -1px 0 rgba(255,255,255,.45);
transition-duration: .08s;
}
/* Label gravé */
.lux-push__label {
position: absolute; inset: 0;
display: grid; place-items: center; z-index: 4;
font-size: clamp(14px, 1.65vw, 16px);
font-weight: 500; letter-spacing: .22em; text-transform: uppercase;
user-select: none;
color: rgba(100,96,90,.82);
text-shadow:
0 1px 0 rgba(255,255,255,.88),
0 -1px 0 rgba(80,76,70,.12);
transition: transform .1s ease, filter .1s ease,
color .1s ease, text-shadow .1s ease;
}
.push-wrap:hover .lux-push__label { color: rgba(80,76,70,.90); }
.lux-push:active .lux-push__label {
transform: translateY(1.5px) scale(.982);
color: rgba(70,66,60,.88);
text-shadow:
0 1.5px 3px rgba(80,76,70,.22),
0 -1px 0 rgba(80,76,70,.10);
transition-duration: .08s;
}
/* Halo hover */
.lux-push__halo {
inset: -10px; border-radius: inherit;
background: radial-gradient(circle at 50% 50%,
rgba(255,255,255,.55) 0%, rgba(255,255,255,0) 65%);
filter: blur(10px); opacity: 0;
transition: opacity .28s ease;
}
.push-wrap:hover .lux-push__halo { opacity: 1; }
.lux-push:active .lux-push__halo { opacity: 0; transition-duration: .08s; }
.lux-push:focus-visible {
outline: 2px solid rgba(100,96,90,.32);
outline-offset: 8px;
}
@media (max-width: 600px) {
.lux-push { width: min(300px, 92vw); }
}
@media (prefers-reduced-motion: reduce) {
.lux-push, .lux-push__surface, .lux-push__label,
.lux-push__rim, .lux-push__bevel, .push-wrap::before {
transition: none !important;
}
}
const btn = document.getElementById('luxPush');
function updateLight(e) {
const rect = btn.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;
const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
const cx = clamp(x, 0, 1);
const cy = clamp(y, 0, 1);
/* Reflet spéculaire — suit exactement la souris */
btn.style.setProperty("--mx", `${(cx * 100).toFixed(2)}%`);
btn.style.setProperty("--my", `${(cy * 100).toFixed(2)}%`);
/* Tilt 3D — ±5° horizontal, ±4° vertical */
btn.style.setProperty("--ry", `${((cx - 0.5) * 10).toFixed(2)}deg`);
btn.style.setProperty("--rx", `${((0.5 - cy) * 8).toFixed(2)}deg`);
}
function resetLight() {
btn.style.setProperty("--mx", "50%");
btn.style.setProperty("--my", "24%");
btn.style.setProperty("--ry", "0deg");
btn.style.setProperty("--rx", "0deg");
}
btn.addEventListener("pointermove", updateLight);
btn.addEventListener("pointerleave", resetLight);
btn.addEventListener("blur", resetLight);
.zone-push {
display: grid;
place-items: center;
min-height: 180px;
padding: 40px;
background:
radial-gradient(ellipse at 30% 22%,
rgba(255,255,255,.95), transparent 44%),
linear-gradient(160deg, #f0ede8, #e8e4de 52%, #dedad4);
border-radius: 22px;
overflow: visible; /* pour l'ombre portée */
}