3D carte à retourner
Carte d’information en relief utilisable à la souris, au tactile et au clavier.
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>3D carte à retourner</title>
<style>
* { box-sizing: border-box; }
:root { color-scheme: dark; }
body { min-height: 100vh; margin: 0; display: grid; place-items: center; padding: 26px; color: #f7f0df; font-family: "Copperplate", "Microsoft YaHei", sans-serif; background: radial-gradient(circle at 50% 10%, #313e55, #0d1320 55%); }
main { text-align: center; }
.eyebrow { color: #d8b76c; font-size: 11px; font-weight: 800; letter-spacing: .25em; }
h1 { margin: 10px 0 28px; font: 500 clamp(34px, 7vw, 58px)/1 Georgia, "STSong", serif; }
.scene { width: min(350px, calc(100vw - 52px)); height: 460px; perspective: 1100px; }
.card { position: relative; width: 100%; height: 100%; padding: 0; border: 0; border-radius: 26px; color: inherit; font: inherit; background: transparent; cursor: pointer; transform-style: preserve-3d; transition: transform .75s cubic-bezier(.2,.75,.25,1); }
.card[aria-pressed="true"] { transform: rotateY(180deg); }
.card:focus-visible { outline: 3px solid #f1d28a; outline-offset: 7px; }
.face { position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden; padding: 30px; border: 1px solid rgba(255,255,255,.2); border-radius: 26px; backface-visibility: hidden; box-shadow: 0 32px 80px rgba(0,0,0,.36); }
.front { justify-content: space-between; text-align: left; background: linear-gradient(160deg, rgba(255,255,255,.15), transparent 38%), linear-gradient(145deg, #31566d, #142d44 55%, #0d1c30); }
.front::before { content: ""; position: absolute; width: 260px; height: 260px; top: 82px; left: 44px; border: 1px solid rgba(216,183,108,.45); border-radius: 50%; box-shadow: 0 0 0 35px rgba(216,183,108,.05), 0 0 0 70px rgba(216,183,108,.035); }
.front::after { content: "✦"; position: absolute; top: 154px; left: 132px; color: #f1d28a; font-size: 82px; text-shadow: 0 0 30px rgba(241,210,138,.65); }
.back { transform: rotateY(180deg); justify-content: center; align-items: center; text-align: center; background: linear-gradient(145deg, #7b3e48, #3c263d 62%, #231a31); }
.back::before { content: ""; position: absolute; inset: 16px; border: 1px solid rgba(241,210,138,.35); border-radius: 18px; }
.topline { display: flex; justify-content: space-between; color: #d8b76c; font-size: 11px; letter-spacing: .13em; }
.front-title { position: relative; z-index: 1; }
.front-title strong { display: block; font: 500 37px/1 Georgia, serif; }
.front-title span { display: block; margin-top: 8px; color: #aebdcc; font-size: 11px; letter-spacing: .16em; }
.symbol { color: #f1d28a; font-size: 40px; }
.back h2 { margin: 18px 0 12px; font: 500 34px/1.1 Georgia, "STSong", serif; }
.back p { max-width: 235px; margin: 0; color: #d5c1c4; font-family: "Avenir Next", "Microsoft YaHei", sans-serif; font-size: 13px; line-height: 1.7; }
.hint { margin: 20px 0 0; color: #7d8aa0; font-family: "Avenir Next", "Microsoft YaHei", sans-serif; font-size: 12px; }
@media (hover: hover) { .scene:hover .card:not([aria-pressed="true"]) { transform: rotateY(8deg) rotateX(-3deg); } }
@media (prefers-reduced-motion: reduce) { .card { transition-duration: .01ms; } }
</style>
</head>
<body>
<main>
<span class="eyebrow">CELESTIAL ARCHIVE · NO. 08</span><h1>Ouvrir la carte astrologique</h1>
<div class="scene"><button id="card" class="card" type="button" aria-pressed="false" aria-label="Carte astrologique à retourner">
<span class="face front"><span class="topline"><span>THE NORTH STAR</span><span>VIII</span></span><span class="front-title"><strong>Beichen</strong><span>GUIDANCE · CLARITY</span></span></span>
<span class="face back"><span class="symbol">✧</span><h2>La direction importe plus que la vitesse</h2><p>Quand il y a trop de choix, revenez à la question de départ. Un objectif vraiment important filtrera à votre place le bruit sur le chemin.</p></span>
</button></div>
<p class="hint">Cliquez sur la carte ou appuyez sur Entrée pour la retourner</p>
</main>
<script>
const card = document.querySelector('#card');
card.addEventListener('click', () => card.setAttribute('aria-pressed', String(card.getAttribute('aria-pressed') !== 'true')));
</script>
</body>
</html>