daisy-hook: accept a full "Name: value" header setting, redact the key from logs, retry once; start: brand icons on link and service tiles (trimmed simple-icons + saved favicons, monogram fallback)
All checks were successful
Deploy production / deploy (push) Successful in 1m7s

This commit is contained in:
2026-10-25 13:11:59 +00:00
parent a89a187346
commit 92d6da959d
19 changed files with 379 additions and 29 deletions

View File

@@ -2,6 +2,7 @@
import { enhance } from '$app/forms';
import { invalidate } from '$app/navigation';
import { ago, bytes, duration, timerStatus, type Container } from '#lib/home.js';
import { linkIcon } from '#lib/link-icons.js';
let { data, form } = $props();
@@ -358,7 +359,8 @@
href={s.url}
title="{host_(s.url)} · {s.code ?? '?'}{s.ms != null ? ` · ${s.ms} ms` : ''}"
>
<i class="dot {s.ok === false ? 'bad' : s.ok ? 'ok' : 'off'}"></i>{s.name}
{@render icon(s.url, s.name)}<span class="label">{s.name}</span>
<i class="dot {s.ok === false ? 'bad' : s.ok ? 'ok' : 'off'}"></i>
</a>
</li>
{/each}
@@ -383,7 +385,7 @@
{#if form?.message}<p class="bad sub" role="alert">{form.message}</p>{/if}
{#each sections as [section, links] (section)}
{#if sections.length > 1}<h3>{section}</h3>{/if}
<ul class={editing ? 'list' : 'tiles'}>
<ul class={editing ? 'list' : 'tiles icons'}>
{#each links as l (l.id)}
<li>
{#if editing && editId === l.id}
@@ -406,7 +408,9 @@
<button class="ghost bad" aria-label="Delete {l.title}">✕</button>
</form>
{:else}
<a href={l.url} title={l.url}>{l.title}</a>
<a href={l.url} title={l.url}
>{@render icon(l.url, l.title)}<span class="label">{l.title}</span></a
>
{/if}
</li>
{/each}
@@ -434,6 +438,20 @@
</div>
{/snippet}
{#snippet icon(url: string, title: string)}
{@const ic = linkIcon(url, title)}
{#if ic.kind === 'svg'}
<span class="ico" style:color={ic.color} aria-hidden="true"
><!-- eslint-disable-next-line svelte/no-at-html-tags -- trimmed simple-icons paths from link-icons.json -->
{@html `<svg viewBox="0 0 24 24">${ic.body}</svg>`}</span
>
{:else if ic.kind === 'img'}
<img class="ico" src={ic.src} alt="" width="16" height="16" loading="lazy" decoding="async" />
{:else}
<span class="ico letter" style:background={ic.color} aria-hidden="true">{ic.letter}</span>
{/if}
{/snippet}
{#snippet linkForm(l: { id: number; title: string; url: string; section: string } | null)}
<form
method="POST"
@@ -797,6 +815,50 @@
background: var(--site-hover);
text-decoration: none;
}
/* Icon tiles (links + services): brand-coloured mark on the black/white card, lift on hover. */
.tiles a:has(.ico) {
gap: 7px;
transition:
transform 120ms ease,
border-color 120ms ease,
background 120ms ease;
}
.tiles a:has(.ico):hover {
transform: translateY(-1px);
border-color: var(--site-muted);
}
.tiles.icons {
grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
}
.tiles .label {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
}
.tiles a .dot {
margin: 0 0 0 auto;
flex: none;
}
.ico {
flex: none;
width: 16px;
height: 16px;
display: inline-grid;
place-items: center;
border-radius: 4px;
object-fit: contain;
}
.ico :global(svg) {
width: 15px;
height: 15px;
display: block;
}
.ico.letter {
color: #fff;
font-size: 10px;
font-weight: 700;
line-height: 1;
}
button {
font: inherit;
color: var(--site-text);