mlv2boii 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.html +47 -36
  2. package/loader.svg +36 -29
  3. package/package.json +1 -1
package/index.html CHANGED
@@ -1,6 +1,5 @@
1
- <svg xmlns="http://www.w3.org/2000/svg">
2
- <foreignObject width="100%" height="100%">
3
- <div xmlns="http://www.w3.org/1999/xhtml">
1
+ <!DOCTYPE html>
2
+ <html>
4
3
  <head>
5
4
  <meta charset="UTF-8" />
6
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
@@ -71,13 +70,19 @@
71
70
  @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
72
71
  .skel { background: linear-gradient(100deg, #18181c 30%, #202024 45%, #18181c 60%); background-size: 200% 100%; animation: shimmer 1.6s ease-in-out infinite; }
73
72
 
74
- /* respect the OS "reduce motion" flag everywhere, unconditionally */
75
- @media (prefers-reduced-motion: reduce) {
76
- *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
77
- }
78
-
79
- [data-fx] { will-change: transform, opacity; }
80
- </style>
73
+ [data-fx] { will-change: transform, opacity; }
74
+
75
+ .hero-orb { animation: heroFloat 7s ease-in-out infinite; }
76
+ .hero-line { animation: heroLine 2.8s ease-in-out infinite; }
77
+ @keyframes heroFloat {
78
+ 0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
79
+ 50% { transform: translate3d(0, 12px, 0) scale(1.04); }
80
+ }
81
+ @keyframes heroLine {
82
+ 0%, 100% { opacity: .35; transform: scaleX(.7); }
83
+ 50% { opacity: 1; transform: scaleX(1); }
84
+ }
85
+ </style>
81
86
  </head>
82
87
 
83
88
  <body class="bg-ink-950 text-ink-100 font-sans antialiased min-h-screen">
@@ -90,7 +95,7 @@
90
95
  <a href="#" class="flex items-center gap-2 shrink-0 group">
91
96
  <span class="relative h-2 w-2">
92
97
  <span class="absolute inset-0 rounded-full bg-red-500"></span>
93
- <span class="absolute inset-0 rounded-full bg-red-500 motion-safe:animate-ping opacity-60"></span>
98
+ <span class="absolute inset-0 animate-ping rounded-full bg-red-500 opacity-60"></span>
94
99
  </span>
95
100
  <span class="font-display font-semibold tracking-tight text-[15px] leading-none">mlv2</span>
96
101
  </a>
@@ -107,12 +112,27 @@
107
112
  </div>
108
113
 
109
114
  <div class="border-t border-ink-800/60">
110
- <div id="category-bar" class="mx-auto max-w-6xl px-4 sm:px-6 py-2.5 flex items-center gap-1.5 overflow-x-auto"></div>
115
+ <div id="category-bar" class="mx-auto flex max-w-5xl items-center justify-center gap-1.5 overflow-x-auto px-4 py-2.5 sm:px-6"></div>
111
116
  </div>
112
117
  </header>
113
118
 
114
119
  <!-- ================= MAIN ================= -->
115
- <main class="relative z-10 mx-auto max-w-6xl px-4 sm:px-6 py-8 sm:py-10">
120
+ <main class="relative z-10 mx-auto max-w-5xl px-4 sm:px-6 py-8 sm:py-12">
121
+
122
+ <!-- ================= HERO ================= -->
123
+ <section class="relative mx-auto mb-10 max-w-2xl overflow-hidden rounded-[2rem] border border-ink-700/70 bg-ink-900/65 px-5 py-10 text-center shadow-[0_24px_80px_-40px_rgba(232,20,47,0.5)] sm:px-10 sm:py-14">
124
+ <div class="hero-orb pointer-events-none absolute -right-20 -top-24 h-64 w-64 rounded-full bg-red-500/10 blur-3xl"></div>
125
+ <div class="hero-orb pointer-events-none absolute -bottom-28 -left-20 h-56 w-56 rounded-full bg-red-700/10 blur-3xl" style="animation-delay: -3.5s"></div>
126
+ <div class="relative">
127
+ <div class="mx-auto mb-5 flex w-fit items-center gap-2 rounded-full border border-red-500/25 bg-red-500/[0.07] px-3 py-1 text-[10px] font-mono uppercase tracking-[0.22em] text-red-300">
128
+ <span class="h-1.5 w-1.5 rounded-full bg-red-400 shadow-[0_0_12px_rgba(255,77,97,0.9)]"></span>
129
+ Play something
130
+ </div>
131
+ <h1 class="font-display text-4xl font-semibold tracking-[-0.05em] text-ink-50 sm:text-6xl">Your next <span class="text-red-400">favorite</span> game.</h1>
132
+ <p class="mx-auto mt-4 max-w-md text-sm leading-6 text-ink-300 sm:text-[15px]">A curated shelf of quick escapes, hidden gems, and games worth one more round.</p>
133
+ <div class="hero-line mx-auto mt-7 h-px w-24 bg-gradient-to-r from-transparent via-red-400 to-transparent"></div>
134
+ </div>
135
+ </section>
116
136
 
117
137
  <!-- setup banner, shown only while CONFIG still has placeholder values -->
118
138
  <div id="setup-banner" class="hidden mb-8 rounded-xl border border-red-500/25 bg-red-500/[0.06] px-4 py-3.5">
@@ -121,7 +141,7 @@
121
141
  </div>
122
142
 
123
143
  <!-- skeleton loading state -->
124
- <div id="skeleton-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3.5 sm:gap-4">
144
+ <div id="skeleton-grid" class="grid grid-cols-2 gap-3.5 sm:grid-cols-3 sm:gap-4 md:grid-cols-4 lg:grid-cols-5">
125
145
  </div>
126
146
 
127
147
  <!-- empty state -->
@@ -134,7 +154,7 @@
134
154
  </div>
135
155
 
136
156
  <!-- game grid -->
137
- <div id="grid" class="hidden grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3.5 sm:gap-4"></div>
157
+ <div id="grid" class="hidden grid grid-cols-2 gap-3.5 sm:grid-cols-3 sm:gap-4 md:grid-cols-4 lg:grid-cols-5"></div>
138
158
  </main>
139
159
 
140
160
  <!-- ================= FOOTER ================= -->
@@ -312,20 +332,12 @@ const isConfigured = () =>
312
332
  !CONFIG.databaseId.includes("YOUR_");
313
333
 
314
334
  /* ---------------------------------------------------------------------
315
- Reduced-motion handling the "bypass animations" flag.
316
- Mirrors the Windows / OS "disable animation effects" setting via the
317
- prefers-reduced-motion media query. Every Motion call below funnels
318
- through fx(), which collapses to an instant, durationless jump when
319
- the flag is set — and re-checks live if the user flips it mid-session.
320
- --------------------------------------------------------------------- */
321
- const reduceMotionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
322
- let reduceMotion = reduceMotionQuery.matches;
323
- reduceMotionQuery.addEventListener("change", (e) => (reduceMotion = e.matches));
324
-
325
- function fx(targets, keyframes, options = {}) {
326
- if (reduceMotion) return animate(targets, keyframes, { duration: 0 });
327
- return animate(targets, keyframes, options);
328
- }
335
+ Animation helper. Motion is intentionally kept consistent for every
336
+ visitor so the interface has the same visual rhythm across devices.
337
+ --------------------------------------------------------------------- */
338
+ function fx(targets, keyframes, options = {}) {
339
+ return animate(targets, keyframes, options);
340
+ }
329
341
 
330
342
  /* ------------------------------- state ------------------------------- */
331
343
  let allGames = [];
@@ -435,10 +447,11 @@ function renderGrid() {
435
447
  grid.innerHTML = games
436
448
  .map((g) => {
437
449
  const src = iconSrcFor(g) || monogramSrc(g.name);
438
- return `<button data-fx data-id="${g.$id}" class="group relative aspect-square rounded-2xl border border-ink-700/70 bg-ink-900 overflow-hidden text-left opacity-0 motion-safe:transition-[border-color,box-shadow] motion-safe:duration-300 hover:border-red-500/55 hover:shadow-[0_0_0_1px_rgba(232,20,47,0.35),0_10px_28px_-10px_rgba(232,20,47,0.4)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500/60">
439
- <img src="${src}" alt="${escapeHtml(g.name)}" loading="lazy" class="h-full w-full object-cover motion-safe:transition-transform motion-safe:duration-500 group-hover:scale-[1.07]" onerror="this.onerror=null;this.src='${monogramSrc(g.name)}'" />
440
- <div class="absolute inset-x-0 bottom-0 p-2.5 bg-gradient-to-t from-ink-950/95 via-ink-950/55 to-transparent">
441
- <p class="truncate text-[12.5px] font-medium text-ink-50 leading-tight">${escapeHtml(g.name)}</p>
450
+ return `<button data-fx data-id="${g.$id}" class="group relative aspect-square overflow-hidden rounded-2xl border border-ink-700/70 bg-ink-900 text-left opacity-0 shadow-[0_12px_28px_-18px_rgba(0,0,0,0.9)] transition-[border-color,box-shadow,transform] duration-300 hover:-translate-y-1 hover:border-red-400/65 hover:shadow-[0_0_0_1px_rgba(232,20,47,0.35),0_18px_32px_-14px_rgba(232,20,47,0.55)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500/60">
451
+ <img src="${src}" alt="${escapeHtml(g.name)}" loading="lazy" class="h-full w-full object-cover transition-transform duration-700 ease-out group-hover:scale-[1.09]" onerror="this.onerror=null;this.src='${monogramSrc(g.name)}'" />
452
+ <div class="absolute inset-0 bg-gradient-to-t from-ink-950/95 via-ink-950/10 to-transparent opacity-90 transition-opacity duration-300 group-hover:opacity-100"></div>
453
+ <div class="absolute inset-x-0 bottom-0 p-3">
454
+ <p class="truncate text-[12.5px] font-medium text-ink-50 leading-tight">${escapeHtml(g.name)}</p>
442
455
  ${g.category ? `<p class="truncate mt-0.5 text-[9.5px] font-mono uppercase tracking-wide text-ink-400">${escapeHtml(g.category)}</p>` : ""}
443
456
  </div>
444
457
  </button>`;
@@ -732,6 +745,4 @@ el("add-game-form").addEventListener("submit", async (e) => {
732
745
  });
733
746
  </script>
734
747
  </body>
735
- </div>
736
- </foreignObject>
737
- </svg>
748
+ </html>
package/loader.svg CHANGED
@@ -1,16 +1,6 @@
1
- <svg xmlns="http://www.w3.org/2000/svg"
2
- xmlns:xhtml="http://www.w3.org/1999/xhtml"
3
- width="100vw"
4
- height="100vh"
5
- viewBox="0 0 100 100"
6
- preserveAspectRatio="none"
7
- style="position:fixed;top:0;left:0;width:100vw;height:100vh;margin:0;padding:0;">
8
-
9
- <foreignObject x="0" y="0" width="100" height="100">
10
-
11
- <xhtml:html xmlns="http://www.w3.org/1999/xhtml"
12
- style="width:100%;height:100%;margin:0;padding:0;">
13
-
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xhtml="http://www.w3.org/1999/xhtml" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
2
+ <foreignObject height="100%" width="100%" y="0" x="0" id="fo">
3
+ <xhtml:html style="width:100%;height:100%;margin:0;padding:0;" xmlns="http://www.w3.org/1999/xhtml">
14
4
  <head>
15
5
  <style>
16
6
  html, body {
@@ -23,11 +13,11 @@
23
13
  }
24
14
 
25
15
  iframe {
26
- position: fixed;
16
+ position: absolute;
27
17
  top: 0;
28
18
  left: 0;
29
- width: 100vw;
30
- height: 100vh;
19
+ width: 100%;
20
+ height: 100%;
31
21
  border: 0;
32
22
  margin: 0;
33
23
  padding: 0;
@@ -37,39 +27,56 @@
37
27
  </head>
38
28
 
39
29
  <body>
30
+
40
31
  <iframe id="mlv2" src="about:blank"></iframe>
41
32
 
42
33
  <script>
43
34
  //<![CDATA[
44
- (async function() {
35
+ (async function () {
45
36
  try {
46
37
  const response = await fetch(
47
- 'https://cdn.jsdelivr.net/npm/mlv2boii/index.html'
38
+ "https://cdn.jsdelivr.net/npm/mlv2boii/index.html"
48
39
  );
49
40
 
50
41
  if (!response.ok) {
51
- throw new Error('HTTP ' + response.status);
42
+ throw new Error("HTTP " + response.status);
52
43
  }
53
44
 
54
45
  const html = await response.text();
55
-
56
- const iframe = document.getElementById('mlv2');
57
- const doc = iframe.contentDocument ||
58
- iframe.contentWindow.document;
46
+ const iframe = document.getElementById("mlv2");
47
+ const doc = iframe.contentDocument;
59
48
 
60
49
  doc.open();
61
- doc.write(html);
50
+ // Inject viewport CSS into the iframe document before writing body content
51
+ doc.write(`
52
+ <!DOCTYPE html>
53
+ <html>
54
+ <head>
55
+ <style>
56
+ html, body {
57
+ margin: 0;
58
+ padding: 0;
59
+ width: 100vw;
60
+ height: 100vh;
61
+ overflow: hidden;
62
+ }
63
+ </style>
64
+ </head>
65
+ <body>
66
+ ${html}
67
+ </body>
68
+ </html>
69
+ `);
62
70
  doc.close();
63
71
 
64
- } catch (error) {
65
- console.error('MLV2 loader error:', error);
72
+ } catch (e) {
73
+ console.error("MLV2 loader error:", e);
66
74
  }
67
75
  })();
68
76
  //]]>
69
77
  </script>
70
- </body>
71
78
 
79
+ </body>
72
80
  </xhtml:html>
73
-
74
81
  </foreignObject>
75
- </svg>
82
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mlv2boii",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {