remove emojis with real icons
All checks were successful
Test and deploy staging / staging (push) Successful in 1m46s
All checks were successful
Test and deploy staging / staging (push) Successful in 1m46s
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Music2 from 'lucide-svelte/icons/music-2';
|
||||
let { src, class: className = '' }: { src?: string; class?: string } = $props();
|
||||
let failed = $state(false);
|
||||
$effect(() => {
|
||||
@@ -18,6 +19,6 @@
|
||||
class="flex h-full items-center justify-center text-2xl text-gray-500"
|
||||
aria-hidden="true"
|
||||
>
|
||||
♫
|
||||
<Music2 size={28} />
|
||||
</div>{/if}
|
||||
</div>
|
||||
|
||||
@@ -6,9 +6,6 @@ import postgres from 'postgres';
|
||||
const client = postgres('postgresql://postgres:postgres@localhost:5432/db');
|
||||
const db = drizzle(client, { schema });
|
||||
|
||||
await db.insert(topics).values([
|
||||
{ name: 'Math', emoji: '👍' },
|
||||
{ name: 'Programming', emoji: '👍' }
|
||||
]);
|
||||
await db.insert(topics).values([{ name: 'Math' }, { name: 'Programming' }]);
|
||||
|
||||
process.exit(0);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { page } from '$app/state';
|
||||
import { getSeo } from '$lib/seo';
|
||||
import CopyButton from '$lib/components/CopyButton.svelte';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
import SiOsu from '~icons/simple-icons/osu';
|
||||
import SiSteam from '~icons/simple-icons/steam';
|
||||
import SiTwitch from '~icons/simple-icons/twitch';
|
||||
@@ -257,7 +258,8 @@
|
||||
<a
|
||||
href="https://git.stanrunge.dev/stan/personal-website"
|
||||
rel="external"
|
||||
class="hover:text-[var(--site-text)]">source ↗</a
|
||||
class="inline-flex items-center gap-1 hover:text-[var(--site-text)]"
|
||||
>source <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
</div>
|
||||
<nav class="flex flex-wrap items-center justify-center gap-1" aria-label="Social links">
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import { resolve } from '$app/paths';
|
||||
import portrait from '$lib/assets/stan.jpg?url';
|
||||
import ProgressBar from '$lib/components/ProgressBar.svelte';
|
||||
import ArrowRight from 'lucide-svelte/icons/arrow-right';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
import Mail from 'lucide-svelte/icons/mail';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data }: PageProps = $props();
|
||||
@@ -21,7 +24,7 @@
|
||||
},
|
||||
{
|
||||
name: 'animaldex',
|
||||
subtitle: 'add neighborhood pets to the world map 😼',
|
||||
subtitle: 'add neighborhood pets to the world map',
|
||||
href: '/projects/animaldex',
|
||||
external: false
|
||||
},
|
||||
@@ -68,15 +71,26 @@
|
||||
<a
|
||||
href="https://git.stanrunge.dev/stan"
|
||||
rel="external"
|
||||
class="hover:text-[var(--site-text)]">git ↗</a
|
||||
class="inline-flex items-center gap-1 hover:text-[var(--site-text)]"
|
||||
>git <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
<a href="https://x.com/stanrunge" rel="external" class="hover:text-[var(--site-text)]"
|
||||
>twitter ↗</a
|
||||
<a
|
||||
href="https://x.com/stanrunge"
|
||||
rel="external"
|
||||
class="inline-flex items-center gap-1 hover:text-[var(--site-text)]"
|
||||
>twitter <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
<a href="https://esports.vash.software" rel="external" class="hover:text-[var(--site-text)]"
|
||||
>vash esports ↗</a
|
||||
<a
|
||||
href="https://esports.vash.software"
|
||||
rel="external"
|
||||
class="inline-flex items-center gap-1 hover:text-[var(--site-text)]"
|
||||
>vash esports <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
<a
|
||||
href="mailto:stan@stanrunge.dev"
|
||||
class="inline-flex items-center gap-1 hover:text-[var(--site-text)]"
|
||||
>email <Mail size={14} aria-hidden="true" /></a
|
||||
>
|
||||
<a href="mailto:stan@stanrunge.dev" class="hover:text-[var(--site-text)]">email ↗</a>
|
||||
</nav>
|
||||
</div>
|
||||
<img
|
||||
@@ -93,7 +107,11 @@
|
||||
|
||||
<section aria-labelledby="projects-heading" class="border-t border-[var(--site-border)] pt-8">
|
||||
<h2 id="projects-heading" class="mb-4 text-2xl font-semibold tracking-tight">
|
||||
<a href={resolve('/projects')} class="hover:text-[var(--site-muted)]">projects ↗</a>
|
||||
<a
|
||||
href={resolve('/projects')}
|
||||
class="inline-flex items-center gap-1 hover:text-[var(--site-muted)]"
|
||||
>projects <ArrowRight size={20} aria-hidden="true" /></a
|
||||
>
|
||||
</h2>
|
||||
<ul>
|
||||
{#each projects as project (project.name)}
|
||||
@@ -108,7 +126,11 @@
|
||||
<span class="block">{project.name}</span>
|
||||
<span class="mt-1 block text-base text-[var(--site-muted)]">{project.subtitle}</span
|
||||
>
|
||||
</span><span aria-hidden="true" class="shrink-0 text-[var(--site-muted)]">↗</span>
|
||||
</span><ExternalLink
|
||||
size={18}
|
||||
aria-hidden="true"
|
||||
class="shrink-0 text-[var(--site-muted)]"
|
||||
/>
|
||||
</a>
|
||||
{:else}
|
||||
<a
|
||||
@@ -119,7 +141,11 @@
|
||||
<span class="block">{project.name}</span>
|
||||
<span class="mt-1 block text-base text-[var(--site-muted)]">{project.subtitle}</span
|
||||
>
|
||||
</span><span aria-hidden="true" class="shrink-0 text-[var(--site-muted)]">↗</span>
|
||||
</span><ArrowRight
|
||||
size={18}
|
||||
aria-hidden="true"
|
||||
class="shrink-0 text-[var(--site-muted)]"
|
||||
/>
|
||||
</a>
|
||||
{/if}
|
||||
</li>
|
||||
@@ -129,7 +155,11 @@
|
||||
|
||||
<section aria-labelledby="lists-heading" class="pt-14 sm:pt-20">
|
||||
<h2 id="lists-heading" class="mb-4 text-2xl font-semibold tracking-tight">
|
||||
<a href={resolve('/lists')} class="hover:text-[var(--site-muted)]">lists ↗</a>
|
||||
<a
|
||||
href={resolve('/lists')}
|
||||
class="inline-flex items-center gap-1 hover:text-[var(--site-muted)]"
|
||||
>lists <ArrowRight size={20} aria-hidden="true" /></a
|
||||
>
|
||||
</h2>
|
||||
<ul>
|
||||
{#each data.lists as list (list.id)}
|
||||
@@ -140,12 +170,13 @@
|
||||
>
|
||||
<span class="flex flex-wrap items-center justify-between gap-x-6 gap-y-1">
|
||||
<span>{list.name}</span>
|
||||
<span class="text-base text-[var(--site-muted)]">
|
||||
<span class="inline-flex items-center gap-1 text-base text-[var(--site-muted)]">
|
||||
{#if list.isProgress && data.user}
|
||||
{list.total ? Math.round((list.checked / list.total) * 100) : 0}% · {list.checked}/{list.total}
|
||||
{:else}
|
||||
{list.total} {list.total === 1 ? 'item' : 'items'}
|
||||
{/if} ↗
|
||||
{/if}
|
||||
<ArrowRight size={16} aria-hidden="true" />
|
||||
</span>
|
||||
</span>
|
||||
{#if list.isProgress}<span class="mt-3 block"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { enhance } from '$app/forms';
|
||||
import { resolve } from '$app/paths';
|
||||
import ArrowLeft from 'lucide-svelte/icons/arrow-left';
|
||||
import ArrowRight from 'lucide-svelte/icons/arrow-right';
|
||||
|
||||
let { data, form } = $props();
|
||||
|
||||
@@ -24,7 +26,8 @@
|
||||
<div class="mx-auto max-w-5xl px-4 py-10 sm:px-6 sm:py-16">
|
||||
<a
|
||||
href={resolve('/blog')}
|
||||
class="text-base text-[var(--site-muted)] hover:text-[var(--site-text)]">← blog</a
|
||||
class="inline-flex items-center gap-1 text-base text-[var(--site-muted)] hover:text-[var(--site-text)]"
|
||||
><ArrowLeft size={16} aria-hidden="true" /> blog</a
|
||||
>
|
||||
<div class="mt-5 mb-8 flex flex-wrap items-end justify-between gap-4">
|
||||
<div>
|
||||
@@ -34,7 +37,8 @@
|
||||
{#if data.blogArticle.status === 'published'}
|
||||
<a
|
||||
href={resolve('/blog/[slug]', { slug: data.blogArticle.slug })}
|
||||
class="text-base underline underline-offset-4">view article ↗</a
|
||||
class="inline-flex items-center gap-1 text-base underline underline-offset-4"
|
||||
>view article <ArrowRight size={16} aria-hidden="true" /></a
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import ArrowLeft from 'lucide-svelte/icons/arrow-left';
|
||||
import Check from 'lucide-svelte/icons/check';
|
||||
import { enhance } from '$app/forms';
|
||||
import ListPictureDropzone from '$lib/components/ListPictureDropzone.svelte';
|
||||
import ProgressBar from '$lib/components/ProgressBar.svelte';
|
||||
@@ -48,7 +50,8 @@
|
||||
<section class="mx-auto max-w-4xl space-y-6 px-4 py-10 sm:px-6 sm:py-14">
|
||||
<a
|
||||
href={resolve('/lists')}
|
||||
class="text-base text-[var(--site-muted)] hover:text-[var(--site-text)]">← lists</a
|
||||
class="inline-flex items-center gap-1 text-base text-[var(--site-muted)] hover:text-[var(--site-text)]"
|
||||
><ArrowLeft size={16} aria-hidden="true" /> lists</a
|
||||
>
|
||||
<div class="flex flex-wrap items-end justify-between gap-4">
|
||||
<div>
|
||||
@@ -173,7 +176,7 @@
|
||||
class="flex h-8 w-8 items-center justify-center rounded-full border border-[var(--site-border)] text-base"
|
||||
aria-label={`${completed.has(item.id) ? 'Uncheck' : 'Check'} ${item.name}`}
|
||||
>
|
||||
{completed.has(item.id) ? '✓' : ''}
|
||||
{#if completed.has(item.id)}<Check size={16} aria-hidden="true" />{/if}
|
||||
</button>
|
||||
</form>
|
||||
{/if}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { resolve } from '$app/paths';
|
||||
import ArrowRight from 'lucide-svelte/icons/arrow-right';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
|
||||
const projects = [
|
||||
{ name: 'catchemall', href: '/projects/catch-em-all', external: false },
|
||||
@@ -30,18 +32,22 @@
|
||||
rel="external"
|
||||
class="flex items-center justify-between gap-4 py-5 hover:text-[var(--site-muted)]"
|
||||
>
|
||||
<span>{project.name}</span><span aria-hidden="true" class="text-[var(--site-muted)]"
|
||||
>↗</span
|
||||
>
|
||||
<span>{project.name}</span><ExternalLink
|
||||
size={18}
|
||||
aria-hidden="true"
|
||||
class="text-[var(--site-muted)]"
|
||||
/>
|
||||
</a>
|
||||
{:else}
|
||||
<a
|
||||
href={resolve(project.href)}
|
||||
class="flex items-center justify-between gap-4 py-5 hover:text-[var(--site-muted)]"
|
||||
>
|
||||
<span>{project.name}</span><span aria-hidden="true" class="text-[var(--site-muted)]"
|
||||
>↗</span
|
||||
>
|
||||
<span>{project.name}</span><ArrowRight
|
||||
size={18}
|
||||
aria-hidden="true"
|
||||
class="text-[var(--site-muted)]"
|
||||
/>
|
||||
</a>
|
||||
{/if}
|
||||
</li>
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import { onMount, onDestroy, tick } from 'svelte';
|
||||
import { resolve } from '$app/paths';
|
||||
import { page } from '$app/state';
|
||||
import ArrowRight from 'lucide-svelte/icons/arrow-right';
|
||||
import PawPrint from 'lucide-svelte/icons/paw-print';
|
||||
import X from 'lucide-svelte/icons/x';
|
||||
import type { Map as MaptilerMap, Marker as MaptilerMarker } from '@maptiler/sdk';
|
||||
|
||||
interface TrailPoint {
|
||||
@@ -223,7 +226,11 @@
|
||||
el.style.backgroundSize = 'cover';
|
||||
el.style.backgroundPosition = 'center';
|
||||
} else {
|
||||
el.textContent = '🐾';
|
||||
el.innerHTML =
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="4" r="2"/><circle cx="18" cy="8" r="2"/><circle cx="20" cy="16" r="2"/><path d="M9 10a5 5 0 0 1 5 5v3.5a3.5 3.5 0 0 1-6.84 1.045Q6.52 17.48 4.46 16.84A3.5 3.5 0 0 1 5.5 10Z"/></svg>';
|
||||
el.style.display = 'flex';
|
||||
el.style.alignItems = 'center';
|
||||
el.style.justifyContent = 'center';
|
||||
}
|
||||
|
||||
el.onclick = () => selectAnimal(feature);
|
||||
@@ -409,7 +416,8 @@
|
||||
<button
|
||||
onclick={() => (selected = null)}
|
||||
aria-label="Close animal details"
|
||||
class="absolute top-3 right-3 rounded bg-black px-3 py-1 text-white">✕</button
|
||||
class="absolute top-3 right-3 flex h-8 w-8 items-center justify-center rounded bg-black text-white"
|
||||
><X size={18} aria-hidden="true" /></button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -450,9 +458,9 @@
|
||||
</div>
|
||||
<a
|
||||
href={resolve(`/projects/animaldex/register?animalId=${selected.animalId}`)}
|
||||
class="mt-5 inline-block text-base underline underline-offset-4"
|
||||
class="mt-5 inline-flex items-center gap-1 text-base underline underline-offset-4"
|
||||
>
|
||||
i saw this animal too ↗
|
||||
i saw this animal too <ArrowRight size={16} aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -478,7 +486,7 @@
|
||||
class="h-12 w-12 rounded object-cover"
|
||||
/>{:else}<span
|
||||
class="flex h-12 w-12 items-center justify-center rounded bg-[var(--site-surface)]"
|
||||
>🐾</span
|
||||
><PawPrint size={24} aria-hidden="true" /></span
|
||||
>{/if}
|
||||
<span class="min-w-0">
|
||||
<span class="block font-medium">{animal.animalName || animal.species}</span>
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
import type { PageData } from './$types';
|
||||
import { invalidateAll } from '$app/navigation';
|
||||
import { resolve } from '$app/paths';
|
||||
import ArrowLeft from 'lucide-svelte/icons/arrow-left';
|
||||
import Bot from 'lucide-svelte/icons/bot';
|
||||
import Check from 'lucide-svelte/icons/check';
|
||||
import MapPin from 'lucide-svelte/icons/map-pin';
|
||||
import PawPrint from 'lucide-svelte/icons/paw-print';
|
||||
import X from 'lucide-svelte/icons/x';
|
||||
|
||||
let { data }: { data: PageData } = $props();
|
||||
|
||||
@@ -40,8 +46,10 @@
|
||||
</div>
|
||||
{:else}
|
||||
<section class="mx-auto max-w-4xl px-4 py-10 sm:px-6 sm:py-14">
|
||||
<a href={resolve('/projects/animaldex')} class="text-base text-[var(--site-muted)]"
|
||||
>← animaldex</a
|
||||
<a
|
||||
href={resolve('/projects/animaldex')}
|
||||
class="inline-flex items-center gap-1 text-base text-[var(--site-muted)]"
|
||||
><ArrowLeft size={16} aria-hidden="true" /> animaldex</a
|
||||
>
|
||||
<div class="mt-5 mb-8 flex flex-wrap items-end justify-between gap-4">
|
||||
<h1 class="text-4xl font-semibold tracking-tight">animaldex admin</h1>
|
||||
@@ -65,7 +73,9 @@
|
||||
{#if item.photoUrl}
|
||||
<img src={item.photoUrl} alt="" class="h-full w-full object-cover" />
|
||||
{:else}
|
||||
<div class="flex h-full items-center justify-center text-2xl">🐾</div>
|
||||
<div class="flex h-full items-center justify-center">
|
||||
<PawPrint size={28} aria-hidden="true" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
@@ -81,8 +91,8 @@
|
||||
</span>
|
||||
</div>
|
||||
{#if item.aiBreedSuggestion}
|
||||
<p class="mt-1 text-base text-[var(--site-muted)]">
|
||||
🤖 AI: {item.aiBreedSuggestion} ({Math.round(
|
||||
<p class="mt-1 flex items-center gap-1 text-base text-[var(--site-muted)]">
|
||||
<Bot size={16} aria-hidden="true" /> AI: {item.aiBreedSuggestion} ({Math.round(
|
||||
(item.aiBreedConfidence ?? 0) * 100
|
||||
)}%)
|
||||
</p>
|
||||
@@ -97,8 +107,9 @@
|
||||
})}
|
||||
{#if item.reporterName}· by {item.reporterName}{/if}
|
||||
</p>
|
||||
<p class="mt-0.5 text-base text-[var(--site-muted)]">
|
||||
📍 {item.sightingLat.toFixed(5)}, {item.sightingLng.toFixed(5)}
|
||||
<p class="mt-0.5 flex items-center gap-1 text-base text-[var(--site-muted)]">
|
||||
<MapPin size={16} aria-hidden="true" />
|
||||
{item.sightingLat.toFixed(5)}, {item.sightingLng.toFixed(5)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -106,16 +117,22 @@
|
||||
<button
|
||||
onclick={() => moderate(item.animalId, 'accept')}
|
||||
disabled={actionLoading !== null || status === 'accepted'}
|
||||
class="flex-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
class="inline-flex flex-1 items-center justify-center gap-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
>
|
||||
{actionLoading === `animals-${item.animalId}-accept` ? '…' : '✓ Accept'}
|
||||
{#if actionLoading === `animals-${item.animalId}-accept`}…{:else}<Check
|
||||
size={16}
|
||||
aria-hidden="true"
|
||||
/> Accept{/if}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => moderate(item.animalId, 'deny')}
|
||||
disabled={actionLoading !== null || status === 'denied'}
|
||||
class="flex-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
class="inline-flex flex-1 items-center justify-center gap-1 rounded border border-[var(--site-border)] py-2 text-base disabled:opacity-50"
|
||||
>
|
||||
{actionLoading === `animals-${item.animalId}-deny` ? '…' : '✕ Deny'}
|
||||
{#if actionLoading === `animals-${item.animalId}-deny`}…{:else}<X
|
||||
size={16}
|
||||
aria-hidden="true"
|
||||
/> Deny{/if}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { goto } from '$app/navigation';
|
||||
import ArrowLeft from 'lucide-svelte/icons/arrow-left';
|
||||
import X from 'lucide-svelte/icons/x';
|
||||
|
||||
const animalId = $derived($page.url.searchParams.get('animalId'));
|
||||
const isNewSighting = $derived(!!animalId);
|
||||
@@ -240,7 +242,8 @@
|
||||
<section class="mx-auto max-w-3xl px-4 py-10 sm:px-6 sm:py-14">
|
||||
<a
|
||||
href={resolve('/projects/animaldex')}
|
||||
class="text-base text-[var(--site-muted)] hover:text-[var(--site-text)]">← animaldex</a
|
||||
class="inline-flex items-center gap-1 text-base text-[var(--site-muted)] hover:text-[var(--site-text)]"
|
||||
><ArrowLeft size={16} aria-hidden="true" /> animaldex</a
|
||||
>
|
||||
<h1 class="mt-5 text-4xl font-semibold tracking-tight sm:text-5xl">
|
||||
{isNewSighting ? 'add a sighting' : 'add an animal'}
|
||||
@@ -278,7 +281,7 @@
|
||||
onclick={() => removePhoto(i)}
|
||||
aria-label={`Remove photo ${i + 1}`}
|
||||
class="absolute top-1 right-1 flex h-5 w-5 items-center justify-center rounded-full bg-black/60 text-xs text-white"
|
||||
>✕</button
|
||||
><X size={12} aria-hidden="true" /></button
|
||||
>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import Check from 'lucide-svelte/icons/check';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
import { horses, race, type Horse } from '$lib/derby/data';
|
||||
import { scenarios } from '$lib/derby/practice';
|
||||
import { races } from '$lib/derby/races';
|
||||
@@ -497,7 +499,9 @@
|
||||
<ol class="steps">
|
||||
{#each steps as st, i (st.title)}
|
||||
<li class:done={st.done}>
|
||||
<span class="step-n">{st.done ? '✓' : i + 1}</span>
|
||||
<span class="step-n"
|
||||
>{#if st.done}<Check size={16} aria-hidden="true" />{:else}{i + 1}{/if}</span
|
||||
>
|
||||
<div>
|
||||
<a href={st.href}>{st.title}</a>
|
||||
<p>{st.detail}</p>
|
||||
@@ -969,7 +973,9 @@
|
||||
</ul>
|
||||
<div class="source-links">
|
||||
{#each race.sources as s (s.href)}
|
||||
<a href={s.href} target="_blank" rel="noreferrer">{s.label} ↗</a>
|
||||
<a href={s.href} target="_blank" rel="noreferrer"
|
||||
>{s.label} <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1915,6 +1921,9 @@
|
||||
margin-top: 16px;
|
||||
}
|
||||
.source-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 0.76rem;
|
||||
border: 1px solid #07100c;
|
||||
border-radius: 99px;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { untrack } from 'svelte';
|
||||
import ExternalLink from 'lucide-svelte/icons/external-link';
|
||||
import { races, type Runner } from '$lib/derby/races';
|
||||
import { betValue, fairOdds, formatTime, placings } from '$lib/derby/model';
|
||||
import {
|
||||
@@ -708,7 +709,9 @@
|
||||
</ul>
|
||||
<div class="source-links">
|
||||
{#each race.sources as s (s.href)}
|
||||
<a href={s.href} target="_blank" rel="noreferrer">{s.label} ↗</a>
|
||||
<a href={s.href} target="_blank" rel="noreferrer"
|
||||
>{s.label} <ExternalLink size={14} aria-hidden="true" /></a
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1518,6 +1521,9 @@
|
||||
margin-top: 16px;
|
||||
}
|
||||
.source-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 0.76rem;
|
||||
border: 1px solid #07100c;
|
||||
border-radius: 99px;
|
||||
|
||||
Reference in New Issue
Block a user