/* Certificate page: 3D and animation (certificate-fx.js, founder 2026-10-09: make the app pages beautiful with 3D
   animations like Website Analytics). Everything is outside the certificate or switched off while the download file is
   drawn (html.cx-capture), so the PNG, JPG and PDF stay exactly as they were. */
.cx-dust { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
#certRoot { position: relative; z-index: 1; }
.cx-scene { position: relative; perspective: 2200px; perspective-origin: 50% 30%; }
.cx-rays { position: absolute; left: 50%; top: 22%; width: 150%; aspect-ratio: 1; transform: translate(-50%, -50%); z-index: -1; pointer-events: none; border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, rgba(245, 184, 46, .10) 0 6deg, transparent 6deg 18deg);
  -webkit-mask: radial-gradient(closest-side, #000 25%, transparent 100%); mask: radial-gradient(closest-side, #000 25%, transparent 100%);
  animation: cxSpin 80s linear infinite; opacity: .9; }
.cx-rays::after { content: ""; position: absolute; inset: 28%; border-radius: 50%; background: radial-gradient(closest-side, rgba(245, 184, 46, .22), transparent); animation: cxGlow 5s ease-in-out infinite; }
@keyframes cxSpin { to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes cxGlow { 50% { opacity: .45; transform: scale(.92); } }

.cx-stage { position: relative; transform-style: preserve-3d; transform: rotateX(var(--rx, 0deg)) rotateY(calc(var(--ry, 0deg) + var(--flip, 0deg)));
  transition: transform .45s cubic-bezier(.2, .7, .2, 1); }
.cx-stage.is-flipping { transition: transform 1.1s cubic-bezier(.5, 0, .2, 1); }
.cx-stage.is-flipped { --flip: 180deg; }
.cx-stage > .certificate { backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.cx-in { animation: cxIn 1.5s cubic-bezier(.16, .8, .22, 1) both; }
@keyframes cxIn { 0% { opacity: 0; transform: translateY(70px) rotateX(58deg) scale(.86); } 55% { opacity: 1; } 100% { opacity: 1; transform: none; } }

/* Glare under the pointer, and one gold light sweep after it opens */
.cx-glare { position: absolute; inset: 0; z-index: 4; pointer-events: none; overflow: hidden; transform: translateZ(1px); border-radius: 6px; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  background: radial-gradient(520px circle at var(--mx, 50%) var(--my, 30%), rgba(255, 236, 180, .13), transparent 46%); opacity: 0; transition: opacity .3s; }
.cx-scene:hover .cx-glare { opacity: 1; }
.cx-sweep { position: absolute; inset: 0; z-index: 5; pointer-events: none; overflow: hidden; transform: translateZ(2px); backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.cx-sweep::before { content: ""; position: absolute; top: -20%; bottom: -20%; width: 34%; left: -40%; transform: skewX(-18deg);
  background: linear-gradient(90deg, transparent, rgba(255, 228, 150, .0) 10%, rgba(255, 236, 180, .28) 50%, transparent 90%); animation: cxSweep 1.6s .9s ease-in-out both; }
@keyframes cxSweep { to { left: 120%; } }

/* Sparkles floating in front of the certificate (they move against it when it tilts) */
.cx-spark { position: absolute; z-index: 6; width: 6px; height: 6px; pointer-events: none; transform: translateZ(70px); }
.cx-spark::before { content: ""; position: absolute; inset: 0; background: #ffe7a3; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  filter: drop-shadow(0 0 4px #f5b82e); animation: cxTwinkle var(--d, 3s) var(--dl, 0s) ease-in-out infinite; }
@keyframes cxTwinkle { 0%, 100% { opacity: 0; transform: scale(.3) rotate(0deg); } 50% { opacity: 1; transform: scale(1.5) rotate(90deg); } }

/* Inside the certificate (switched off for the download): the seal turns like a coin, the crest glows,
   the signature writes itself, the corners glint */
.cx-on .certificate.gx .gx-seal svg { animation: cxCoin 9s 2.2s ease-in-out infinite; transform-origin: 50% 39%; }
@keyframes cxCoin { 0%, 70% { transform: perspective(500px) rotateY(0deg); } 85%, 100% { transform: perspective(500px) rotateY(360deg); } }
.cx-on .certificate.gx .gx-crest-img { animation: cxCrest 4.5s ease-in-out infinite; }
@keyframes cxCrest { 50% { filter: drop-shadow(0 0 34px rgba(245, 184, 46, .55)); transform: translateY(-3px); } }
.cx-on .certificate.gx .gx-sig { animation: cxWrite 2.2s 1.2s cubic-bezier(.45, .1, .3, 1) both; }
@keyframes cxWrite { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 -10% 0 0); } }
.cx-on .certificate.gx .gx-line { animation: cxLine 1s 3s ease-out both; transform-origin: 50% 50%; }
@keyframes cxLine { from { transform: scaleX(0); } }
.cx-on .certificate.gx .gx-corner svg { animation: cxCorner 6s ease-in-out infinite; }
@keyframes cxCorner { 0%, 80%, 100% { filter: none; } 88% { filter: drop-shadow(0 0 8px #ffd56b) brightness(1.4); } }

/* Buttons: the Download button shines, the share buttons rise in and lift */
.cx-on #certPngBtn { position: relative; overflow: hidden; isolation: isolate; }
.cx-on #certPngBtn::after { content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 40%; transform: skewX(-20deg); background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), transparent); animation: cxBtn 3.6s 2s ease-in-out infinite; pointer-events: none; }
@keyframes cxBtn { 0%, 60% { left: -60%; } 100% { left: 140%; } }
.cx-flipbtn { display: inline-flex; align-items: center; gap: 8px; }
.cx-flipbtn svg { width: 18px; height: 18px; }
.cx-on .gx-soc, .cx-on .cert-share-actions .btn { transition: transform .2s ease, box-shadow .2s ease, border-color .2s, background .2s; }
.cx-on .gx-soc:hover, .cx-on .cert-share-actions .btn:hover { transform: translateY(-3px) perspective(400px) rotateX(8deg); box-shadow: 0 12px 22px -12px rgba(245, 184, 46, .7); }
.cx-rise { animation: cxRise .7s cubic-bezier(.2, .7, .2, 1) both; animation-delay: calc(1.3s + var(--i, 0) * 70ms); }
@keyframes cxRise { from { opacity: 0; transform: translateY(16px); } }
.cx-on .cert-verified svg path { stroke-dasharray: 14; animation: cxTick .8s 1.8s ease-out both; }
@keyframes cxTick { from { stroke-dashoffset: 14; } }

/* The back of the certificate */
.cx-back { position: absolute; inset: 0; z-index: 3; transform: rotateY(180deg); backface-visibility: hidden; -webkit-backface-visibility: hidden; overflow: hidden; border-radius: 6px;
  border: 2px solid #f5b82e; color: #f5f6fb; background: radial-gradient(90% 70% at 50% 18%, #17255a 0%, #0c1430 45%, #070b18 100%);
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center; padding: 54px 40px 40px; }
.cx-back::before { content: ""; position: absolute; inset: 12px; border: 1px solid rgba(245, 184, 46, .5); pointer-events: none; }
.cx-back-in { position: relative; width: 100%; max-width: 640px; display: flex; flex-direction: column; align-items: center; gap: 16px; }
.cx-back h2 { margin: 0; font: 900 clamp(1.4rem, 3.2vw, 2rem)/1.2 "Cinzel", Georgia, serif; letter-spacing: .14em; color: #f5c451; }
.cx-back-ok { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px; font-weight: 700; font-size: .86rem; color: #062a17; background: linear-gradient(135deg, #a7f3c8, #4ade80); }
.cx-back-ok.is-self { color: #2a1a00; background: linear-gradient(135deg, #ffe08a, #f5b82e); }
.cx-back-ok svg { width: 16px; height: 16px; }
.cx-back-qr { width: 190px; height: 190px; padding: 8px; border-radius: 12px; background: #fff6dc; box-shadow: 0 0 0 2px #f5b82e, 0 0 34px rgba(245, 184, 46, .35); image-rendering: pixelated; }
.cx-back dl { width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; margin: 4px 0 0; text-align: left; }
.cx-back dl div { min-width: 0; padding: 10px 14px; border: 1px solid rgba(245, 184, 46, .28); border-radius: 10px; background: rgba(255, 255, 255, .03); }
.cx-back dl div.is-wide { grid-column: 1 / -1; }
.cx-back dt { font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: #9aa3bd; }
.cx-back dd { margin: 3px 0 0; font-weight: 600; color: #fff; overflow-wrap: anywhere; }
.cx-back p { margin: 0; max-width: 560px; color: #c3cae0; font-size: .92rem; line-height: 1.55; }
.cx-back-row { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.cx-back .btn { white-space: normal; }

/* The download file is being drawn: nothing moves, nothing is turned */
html.cx-capture .cx-stage, html.cx-capture .cx-stage > .certificate { transform: none !important; transition: none !important; animation: none !important; }
html.cx-capture .cx-stage .certificate * { animation: none !important; }
html.cx-capture .cx-back, html.cx-capture .cx-glare, html.cx-capture .cx-sweep, html.cx-capture .cx-spark { display: none !important; }

@media (max-width: 760px) {
  .cx-back { padding: 40px 20px 30px; }
  .cx-back dl { grid-template-columns: minmax(0, 1fr); }
  .cx-spark { display: none; }
  .cx-rays { top: 12%; width: 220%; }
  @keyframes cxIn { 0% { opacity: 0; transform: translateY(50px) rotateX(24deg) scale(.94); } 100% { opacity: 1; transform: none; } }
}
@media print {
  .cx-dust, .cx-rays, .cx-glare, .cx-sweep, .cx-spark, .cx-back, .cx-flipbtn { display: none !important; }
  .cx-stage, .cx-stage > .certificate { transform: none !important; animation: none !important; }
  .cx-scene { perspective: none; }
}
@media (prefers-reduced-motion: reduce) {
  .cx-rays, .cx-rays::after, .cx-in, .cx-sweep::before, .cx-spark::before, .cx-rise, .cx-on .certificate.gx *, .cx-on #certPngBtn::after { animation: none !important; }
  .cx-stage, .cx-stage.is-flipping { transition: none; }
}
.cx-back .btn-primary { background: linear-gradient(135deg, #ffd56b, #f5b82e) !important; color: #2a1a00 !important; border-color: #ffe08a; box-shadow: 0 10px 26px -12px rgba(245, 184, 46, .9); }
.cx-back .btn-secondary { background: rgba(255, 255, 255, .04); color: #fff; border: 1px solid rgba(245, 184, 46, .45); }
