2title: "usmnt_world_cup_roster_tracker"
3description: "US Men's 2026 World Cup roster probability tracker"
4imageUrl: "https://chatgpt.com/backend-api/public_content/enc/eyJpZCI6Im1fNjgxMzk5N2RmMWUwODE5MWE0NGY2ZmE1MTIxOGYyODU6ZmlsZV8wMDAwMDAwMGM4YmM2MWY3YWM2MTgzYzIzMmFjMDZhZiIsInRzIjoiNDg1MDMxIiwicCI6InB5aSIsInNpZyI6IjVhMGZmNzc1ZDYxNTA3MjQ2NzAyYTk4MjAwYmI0YjY4NTA1OTcwOTA0YjExODBhYzNkZjA2ZTdlZjg0YmMwYzgiLCJ2IjoiMCIsImdpem1vX2lkIjpudWxsfQ=="
5author: "dcm31"
6tags: ["val-town"]
obedientTurquoiseGoldfishREADME.md38 matches
56}
5758#image-upload-section {
59background-color: rgba(255, 255, 255, 0.8);
60padding: 20px;
68}
6970#image-upload-section h2 {
71margin-bottom: 15px;
72color: #557492;
73}
7475#image-upload-section p {
76margin-bottom: 15px;
77color: #666;
78}
7980#image-upload {
81opacity: 0;
82position: absolute;
120}
121122#image-container {
123display: none;
124background-color: rgba(255, 255, 255, 0.8);
133}
134135#uploaded-image {
136max-width: 100%;
137max-height: 500px;
177}
178179#cropped-image-container {
180display: none;
181background-color: rgba(255, 255, 255, 0.8);
190}
191192#cropped-image {
193max-width: 100%;
194border-radius: 10px;
215216@media (max-width: 768px) {
217#image-upload-section {
218padding: 15px;
219}
248249@media (max-width: 480px) {
250#image-upload-section {
251padding: 10px;
252}
282</header>
283<main>
284<section id="image-upload-section">
285<h2>Upload Your Image</h2>
286<p>Select an image to crop</p>
287<div class="file-upload-wrapper">
288<span class="file-upload-text">Choose File</span>
289<span class="file-upload-button">Browse</span>
290<input type="file" id="image-upload" accept="image/*">
291</div>
292</section>
293<section id="image-container">
294<img id="uploaded-image" src="#" alt="Uploaded Image">
295<button id="crop-button">Crop Image</button>
296<button id="download-button">Download Cropped Image</button>
297</section>
298<section id="cropped-image-container">
299<h2>Cropped Image</h2>
300<img id="cropped-image" src="#" alt="Cropped Image">
301</section>
302</main>
307308<script>
309const imageUpload = document.getElementById('image-upload');
310const imageContainer = document.getElementById('image-container');
311const uploadedImage = document.getElementById('uploaded-image');
312const cropButton = document.getElementById('crop-button');
313const croppedImageContainer = document.getElementById('cropped-image-container');
314const croppedImage = document.getElementById('cropped-image');
315const downloadButton = document.getElementById('download-button');
316317let cropper;
318319imageUpload.addEventListener('change', (event) => {
320const file = event.target.files[0];
321324325reader.onload = (e) => {
326uploadedImage.src = e.target.result;
327imageContainer.style.display = 'block';
328croppedImageContainer.style.display = 'none';
329downloadButton.style.display = 'none';
330333}
334335cropper = new Cropper(uploadedImage, {
336aspectRatio: 1,
337viewMode: 1,
350if (cropper) {
351const canvas = cropper.getCroppedCanvas();
352croppedImage.src = canvas.toDataURL();
353croppedImageContainer.style.display = 'block';
354downloadButton.style.display = 'inline-block';
355}
359const canvas = document.createElement('canvas');
360const ctx = canvas.getContext('2d');
361const img = new Image();
362363img.onload = () => {
364canvas.width = img.width;
365canvas.height = img.height;
366ctx.drawImage(img, 0, 0, img.width, img.height);
367368const link = document.createElement('a');
369link.href = canvas.toDataURL('image/png');
370link.download = 'cropped_image.png';
371document.body.appendChild(link);
372link.click();
374};
375376img.src = croppedImage.src;
377});
378</script>
74- 'name': The race name.
75- 'description': 1-2 sentences max.
76- 'styleHint': 3-5 descriptive keywords for image generation.
77- 'effectColor': A hex color code (#RRGGBB format) associated with the race.
78- 'borderAnimationHint': OPTIONAL. A single keyword suggesting a subtle border animation style for the active card. Choose from 'shimmer', 'pulse', or 'none'. If unsure, use 'none'.
273/* --- Animated Border Styles --- */
274@keyframes border-shimmer { /* Gradient sweep */
2750% { border-image-source: linear-gradient(90deg, transparent 0%, var(--effect-color) 50%, transparent 100%); }
27625% { border-image-source: linear-gradient(90deg, transparent 25%, var(--effect-color) 75%, transparent 100%); }
27750% { border-image-source: linear-gradient(90deg, transparent 50%, var(--effect-color) 100%); }
27875% { border-image-source: linear-gradient(90deg, var(--effect-color) 0%, transparent 25%); }
279100% { border-image-source: linear-gradient(90deg, var(--effect-color) 50%, transparent 100%); }
280}
281@keyframes border-pulse { /* Simple fade in/out */
288border-width: 2px;
289border-style: solid;
290border-image-slice: 1;
291border-image-source: linear-gradient(90deg, transparent 0%, var(--effect-color) 50%, transparent 100%); /* Initial state */
292animation: border-shimmer var(--border-anim-duration) linear infinite;
293}
298299300/* --- Other Styles (Images, Content, Effects - mostly unchanged) --- */
301.race-card img { pointer-events: none; height: 60%; border-radius: 16px 16px 0 0; width: 100%; object-fit: cover; display: block; background-color: #333;}
302.race-card .card-content { pointer-events: none; padding: 20px; display: flex; flex-direction: column; gap: 12px; flex-grow: 1; position: relative; z-index: 2; background: inherit; border-radius: 0 0 16px 16px;} /* Ensure content bg matches card */
448449const prompt = encodeURIComponent(\`disney fantasy character portrait, \${safeStyleHint}, \${safeName}, detailed illustration, cinematic lighting, high fantasy art style\`);
450const imageUrl = \`http://maxm-imggenurl.web.val.run//\${prompt}.jpg\`; // Using Pollinations.ai as example
451const fallbackColor = safeEffectColor.substring(1);
452const fallbackUrl = \`https://placehold.co/400x400/\${fallbackColor}/1A1A1E?text=\${encodeURIComponent(safeName)}\`;
453454card.innerHTML = \`
455<img src="\${imageUrl}" alt="Image of \${safeName}" loading="lazy" onerror="this.onerror=null; this.src='\${fallbackUrl}'; console.warn('Image failed for \${safeName}. Using fallback.');">
456<div class="\${EFFECT_CONTAINER_CLASS}"><div class="energy-surge"></div></div>
457<div class="card-content">
139body::before {
140content: ""; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
141background-image:
142linear-gradient(to right, rgba(255, 255, 255, 0.05) 1px, transparent 1px),
143linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
386/* Gallery & Contact Placeholders */
387.gallery-grid { display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center; padding: 1rem; }
388.gallery-grid .image-container {
389width: 150px; height: 150px; border-radius: 15px; overflow: hidden;
390border: 1px solid var(--color-border); background: var(--color-bg);
391box-shadow: 0 4px 15px var(--shadow-color);
392}
393.gallery-grid .image-container img { width: 100%; height: 100%; object-fit: cover; }
394395/* Crystal Container for static info page (if used) */
515<h2 class="tab-title" data-translate="galleryTitle">Gallery</h2>
516<div class="gallery-grid">
517<div class="image-container"><img src="https://images.unsplash.com/photo-1677756119517-756a188d2d94?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=600" alt="AI 1"></div>
518<div class="image-container"><img src="https://images.unsplash.com/photo-1696258680260-492036cd6559?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=600" alt="AI 2"></div>
519<div class="image-container"><img src="https://images.unsplash.com/photo-1684495809981-394107651435?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=600" alt="AI 3"></div>
520</div>
521</div>
43}
4445// Set temporary image on "Yes" click
46setCurrentImg(tempYesImg);
4748// Revert back to the default image after 1 second
49setTimeout(() => {
50setCurrentImg(yesImg);
55setIsNoClicked(true);
56setIsYesClicked(false);
57setCurrentImg(noImg); // Keep no image as long as "No" is clicked
58};
59
130width: 100%;
131height: 100%;
132background-image:
133linear-gradient(to right, rgba(200, 200, 200, 0.1) 1px, transparent 1px), /* Slightly darker grid */
134linear-gradient(to bottom, rgba(200, 200, 200, 0.1) 1px, transparent 1px);
67- 'name': The name of the race (string).
68- 'description': A brief description (string, 1-2 sentences maximum).
69- 'styleHint': 3-5 descriptive keywords for generating an image (string).
70- 'effectColor': A valid CSS hexadecimal color code string (e.g., "#RRGGBB").
71
MiniAppStarterindex.tsx3 matches
5import * as db from "./db.ts";
6import { embedMetadata, handleFarcasterEndpoints, name } from "./farcaster.ts";
7import { handleImageEndpoints } from "./image.tsx";
89const app = new Hono();
1011handleImageEndpoints(app);
12handleFarcasterEndpoints(app);
1344<meta name="fc:frame" content={JSON.stringify(embedMetadata(baseUrl, path))} />
45<link rel="icon" href={baseUrl + "/icon"} />
46<meta property="og:image" content={baseUrl + "/image"} />
47</head>
48<body class="bg-white text-black dark:bg-black dark:text-white">
MiniAppStarterimage.tsx12 matches
5import satori from "npm:satori";
67export function handleImageEndpoints(app: Hono) {
8const headers = {
9"Content-Type": "image/png",
10"cache-control": "public, max-age=86400",
11};
12app.get("/image", async (c) => {
13return c.body(await homeImage(), 200, headers);
14});
15app.get("/icon", async (c) => {
16return c.body(await iconImage(), 200, headers);
17});
18}
1920export async function homeImage() {
21return await ogImage(
22<div tw="w-full h-full flex justify-start items-end text-[100px] bg-black text-white p-[50px]">
23<div tw="flex flex-col items-start gap-[10px]">
31}
3233export async function iconImage() {
34return await ogImage(
35<div tw="w-full h-full flex justify-center items-center text-[100px] bg-black text-white p-[50px]">
36<img tw="w-[350px] h-[350px]" src={base64Icon(SquareDashed)} />
45//////////
4647export async function ogImage(body, options = {}) {
48const svg = await satori(
49body,
57if (code === "emoji") {
58const unicode = segment.codePointAt(0).toString(16).toUpperCase();
59return `data:image/svg+xml;base64,` + btoa(await loadEmoji(unicode));
60}
61return "";
94const base64 = Buffer.from(svg).toString("base64");
95// console.log('getIconDataUrl', name, svg, base64)
96return `data:image/svg+xml;base64,${base64}`;
97};
MiniAppStarterfarcaster.ts4 matches
5export const name = "Mini App Starter";
6// export const iconUrl = "https://imgur.com/TrJLlwp.png";
7// export const ogImageUrl = "https://imgur.com/xKVOVUE.png";
89export function embedMetadata(baseUrl: string, path: string = "/") {
10return {
11version: "next",
12imageUrl: baseUrl + "/image",
13button: {
14title: name,
17name: name,
18url: baseUrl + path,
19splashImageUrl: baseUrl + "/icon",
20splashBackgroundColor: "#111111",
21},
55"iconUrl": baseUrl + "/icon",
56"homeUrl": baseUrl,
57"splashImageUrl": baseUrl + "/icon",
58"splashBackgroundColor": "#111111",
59"primaryCategory": "developer-tools",