adarshxs HF Staff commited on
Commit
b3bb47a
·
1 Parent(s): 4c9015e

animations

Browse files
Files changed (2) hide show
  1. .gitignore +4 -0
  2. cards.html +74 -3
.gitignore CHANGED
@@ -1 +1,5 @@
1
  __pycache__/
 
 
 
 
 
1
  __pycache__/
2
+
3
+ .venv/
4
+ __pycache__/
5
+ *.pyc
cards.html CHANGED
@@ -133,12 +133,12 @@
133
  .modal-backdrop::after { animation-duration: 16s; animation-direction: reverse; filter: blur(1px); opacity: 0.22; }
134
  .modal {
135
  width: min(1040px, 100%); max-height: 92vh; overflow: auto; border: 0;
136
- background: transparent; border-radius: 28px; padding: 0;
137
  color: var(--text); transform: translateY(18px) scale(0.96);
138
  }
139
  .modal-backdrop.open .modal { animation: modalDrop 0.52s cubic-bezier(.19,1,.22,1) forwards; }
140
  .modal-shell {
141
- position: relative; isolation: isolate;
142
  display: grid; grid-template-columns: minmax(280px, 390px) minmax(320px, 1fr);
143
  gap: 24px; align-items: stretch; padding: 22px;
144
  border: 1px solid rgba(255,255,255,0.18); border-radius: 28px;
@@ -258,6 +258,44 @@
258
  .sparkles i:nth-child(3) { left: 84%; top: 52%; animation-delay: .82s; }
259
  .sparkles i:nth-child(4) { left: 24%; top: 72%; animation-delay: 1.1s; }
260
  .sparkles i:nth-child(5) { left: 55%; top: 84%; animation-delay: 1.45s; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  .modal-info { display: flex; flex-direction: column; min-width: 0; }
262
  .modal-copy {
263
  margin-top: auto; padding: 14px; border-radius: 16px;
@@ -317,7 +355,7 @@
317
  @media (prefers-reduced-motion: reduce) {
318
  .modal-backdrop::before, .modal-backdrop::after, .modal-shell::before,
319
  .modal-card-stage::before, .showcase-card, .showcase-card::before,
320
- .showcase-art::before, .sparkles i { animation: none !important; }
321
  }
322
 
323
  .legend { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
@@ -737,6 +775,38 @@ function hashCode(s) {
737
  return h;
738
  }
739
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  function openModal(m) {
741
  const rarity = rarityFor(m);
742
  const { v, a } = aggregateVA(m.profile);
@@ -747,6 +817,7 @@ function openModal(m) {
747
  const cardNo = String(Math.abs(hashCode(m.id)) % 999).padStart(3, "0");
748
 
749
  document.getElementById("modal-content").innerHTML = `
 
750
  <div class="modal-shell" style="--foil-a:${top[0].color}; --foil-b:${top[1].color}; --foil-c:${top[2].color}; --rarity-color:var(--r-${rarity});">
751
  <div class="modal-card-stage">
752
  <div class="showcase-card r-${rarity}" aria-label="${escapeHtml(m.name)} trading card">
 
133
  .modal-backdrop::after { animation-duration: 16s; animation-direction: reverse; filter: blur(1px); opacity: 0.22; }
134
  .modal {
135
  width: min(1040px, 100%); max-height: 92vh; overflow: auto; border: 0;
136
+ position: relative; background: transparent; border-radius: 28px; padding: 0;
137
  color: var(--text); transform: translateY(18px) scale(0.96);
138
  }
139
  .modal-backdrop.open .modal { animation: modalDrop 0.52s cubic-bezier(.19,1,.22,1) forwards; }
140
  .modal-shell {
141
+ position: relative; z-index: 1; isolation: isolate;
142
  display: grid; grid-template-columns: minmax(280px, 390px) minmax(320px, 1fr);
143
  gap: 24px; align-items: stretch; padding: 22px;
144
  border: 1px solid rgba(255,255,255,0.18); border-radius: 28px;
 
258
  .sparkles i:nth-child(3) { left: 84%; top: 52%; animation-delay: .82s; }
259
  .sparkles i:nth-child(4) { left: 24%; top: 72%; animation-delay: 1.1s; }
260
  .sparkles i:nth-child(5) { left: 55%; top: 84%; animation-delay: 1.45s; }
261
+ .confetti-field {
262
+ position: absolute; inset: -18px; z-index: 4; pointer-events: none;
263
+ overflow: hidden; border-radius: 30px;
264
+ animation: confettiFieldVanish 4.2s ease forwards;
265
+ }
266
+ .confetti-piece {
267
+ --x: 50%; --drift: 0px; --delay: 0s; --dur: 3s; --spin: 1turn; --size: 18px;
268
+ position: absolute; left: var(--x); top: -42px;
269
+ display: grid; place-items: center; min-width: calc(var(--size) + 12px);
270
+ height: calc(var(--size) + 12px); padding: 0 5px;
271
+ border-radius: 999px; font-size: var(--size); line-height: 1;
272
+ background: rgba(255,255,255,0.10); border: 1px solid rgba(255,255,255,0.16);
273
+ box-shadow: 0 0 18px rgba(255,255,255,0.16), 0 0 28px var(--foil-b);
274
+ backdrop-filter: blur(4px);
275
+ animation: confettiFall var(--dur) cubic-bezier(.16,.8,.35,1) var(--delay) both;
276
+ }
277
+ .confetti-piece.logo {
278
+ font-family: var(--mono); font-weight: 800; letter-spacing: -0.06em;
279
+ color: #0d1117; background: #fff;
280
+ }
281
+ .confetti-piece.hf {
282
+ color: #111; background: linear-gradient(135deg, #ffcc4d, #ff9f1c);
283
+ text-shadow: 0 1px 0 rgba(255,255,255,0.45);
284
+ }
285
+ .confetti-piece.jp {
286
+ color: #fff; background: linear-gradient(135deg, rgba(255,92,138,0.82), rgba(188,140,255,0.62));
287
+ }
288
+ .confetti-piece:nth-child(3n) { filter: hue-rotate(32deg); }
289
+ .confetti-piece:nth-child(4n) { border-radius: 8px; }
290
+ @keyframes confettiFall {
291
+ 0% { transform: translate3d(0, -56px, 0) rotate(0deg); opacity: 1; }
292
+ 78% { opacity: 1; }
293
+ 100% { transform: translate3d(var(--drift), 86vh, 0) rotate(var(--spin)); opacity: 0; }
294
+ }
295
+ @keyframes confettiFieldVanish {
296
+ 0%, 72% { opacity: 1; }
297
+ 100% { opacity: 0; visibility: hidden; }
298
+ }
299
  .modal-info { display: flex; flex-direction: column; min-width: 0; }
300
  .modal-copy {
301
  margin-top: auto; padding: 14px; border-radius: 16px;
 
355
  @media (prefers-reduced-motion: reduce) {
356
  .modal-backdrop::before, .modal-backdrop::after, .modal-shell::before,
357
  .modal-card-stage::before, .showcase-card, .showcase-card::before,
358
+ .showcase-art::before, .sparkles i, .confetti-field, .confetti-piece { animation: none !important; }
359
  }
360
 
361
  .legend { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
 
775
  return h;
776
  }
777
 
778
+ const CONFETTI_MARKS = [
779
+ { text: "🌸", cls: "jp" },
780
+ { text: "💮", cls: "jp" },
781
+ { text: "🍥", cls: "jp" },
782
+ { text: "⛩", cls: "jp" },
783
+ { text: "🗾", cls: "jp" },
784
+ { text: "✨", cls: "jp" },
785
+ { text: "🤗", cls: "hf" },
786
+ { text: "HF", cls: "hf logo" },
787
+ { text: "GH", cls: "logo" },
788
+ { text: "🐙", cls: "logo" },
789
+ ];
790
+
791
+ function confettiHTML(seed) {
792
+ let s = Math.abs(hashCode(seed)) || 1;
793
+ const pieces = [];
794
+ for (let i = 0; i < 34; i++) {
795
+ s = (s * 1664525 + 1013904223) >>> 0;
796
+ const mark = CONFETTI_MARKS[s % CONFETTI_MARKS.length];
797
+ const x = 3 + ((s >>> 8) % 94);
798
+ const drift = ((s >>> 10) % 121) - 60;
799
+ const delay = ((s >>> 16) % 140) / 100;
800
+ const dur = 2.2 + ((s >>> 4) % 24) / 10;
801
+ const spin = ((s % 2) ? 1 : -1) * (0.7 + ((s >>> 12) % 20) / 10);
802
+ const size = 18 + ((s >>> 20) % 15);
803
+ pieces.push(
804
+ `<span class="confetti-piece ${mark.cls}" style="--x:${x}%; --drift:${drift}px; --delay:${delay}s; --dur:${dur.toFixed(1)}s; --spin:${spin.toFixed(1)}turn; --size:${size}px;">${mark.text}</span>`
805
+ );
806
+ }
807
+ return `<div class="confetti-field" aria-hidden="true">${pieces.join("")}</div>`;
808
+ }
809
+
810
  function openModal(m) {
811
  const rarity = rarityFor(m);
812
  const { v, a } = aggregateVA(m.profile);
 
817
  const cardNo = String(Math.abs(hashCode(m.id)) % 999).padStart(3, "0");
818
 
819
  document.getElementById("modal-content").innerHTML = `
820
+ ${confettiHTML(m.id)}
821
  <div class="modal-shell" style="--foil-a:${top[0].color}; --foil-b:${top[1].color}; --foil-c:${top[2].color}; --rarity-color:var(--r-${rarity});">
822
  <div class="modal-card-stage">
823
  <div class="showcase-card r-${rarity}" aria-label="${escapeHtml(m.name)} trading card">