You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
3.6 KiB
189 lines
3.6 KiB
<script lang="ts">
|
|
let {
|
|
title,
|
|
alias,
|
|
href,
|
|
description,
|
|
tag,
|
|
factories
|
|
}: {
|
|
title: string;
|
|
alias?: string;
|
|
href: string;
|
|
description: string;
|
|
tag?: string;
|
|
factories?: readonly string[];
|
|
} = $props();
|
|
</script>
|
|
|
|
<a class="card" {href}>
|
|
<div class="head">
|
|
<span class="title">{title}</span>
|
|
{#if alias}
|
|
<span class="alias">{alias}</span>
|
|
{/if}
|
|
{#if tag}
|
|
<span class="tag">{tag}</span>
|
|
{/if}
|
|
<span class="arrow" aria-hidden="true">
|
|
<svg viewBox="0 0 16 16" width="14" height="14">
|
|
<path
|
|
d="M5 3l5 5-5 5"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="1.8"
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
/>
|
|
</svg>
|
|
</span>
|
|
</div>
|
|
<p class="desc">{description}</p>
|
|
{#if factories && factories.length}
|
|
<div class="factories">
|
|
{#each factories as fn (fn)}
|
|
<code>{fn}</code>
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
</a>
|
|
|
|
<style>
|
|
.card {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.5rem;
|
|
padding: 1.05rem 1.25rem 1.1rem;
|
|
border: 1px solid var(--c-border);
|
|
border-radius: var(--r-lg);
|
|
background: var(--c-bg);
|
|
color: var(--c-fg);
|
|
overflow: hidden;
|
|
transition:
|
|
border-color 180ms var(--ease),
|
|
background-color 180ms var(--ease),
|
|
transform 180ms var(--ease),
|
|
box-shadow 180ms var(--ease);
|
|
}
|
|
|
|
.card::before {
|
|
content: '';
|
|
position: absolute;
|
|
inset: 0;
|
|
border-radius: var(--r-lg);
|
|
padding: 1px;
|
|
background: linear-gradient(135deg, transparent 40%, var(--c-accent) 90%);
|
|
mask:
|
|
linear-gradient(#000 0 0) content-box,
|
|
linear-gradient(#000 0 0);
|
|
mask-composite: exclude;
|
|
-webkit-mask:
|
|
linear-gradient(#000 0 0) content-box,
|
|
linear-gradient(#000 0 0);
|
|
-webkit-mask-composite: xor;
|
|
opacity: 0;
|
|
transition: opacity 180ms var(--ease);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.card:hover {
|
|
border-color: transparent;
|
|
background: var(--c-bg);
|
|
transform: translateY(-2px);
|
|
box-shadow: var(--shadow-md);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.card:hover::before {
|
|
opacity: 1;
|
|
}
|
|
|
|
.head {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.title {
|
|
font-weight: 650;
|
|
font-size: 0.95rem;
|
|
color: var(--c-fg);
|
|
letter-spacing: -0.01em;
|
|
}
|
|
|
|
.alias {
|
|
font-family: var(--font-mono);
|
|
font-size: 0.72rem;
|
|
font-weight: 500;
|
|
color: var(--c-fg-subtle);
|
|
background: var(--c-bg-muted);
|
|
border: 1px solid var(--c-border);
|
|
padding: 0.1em 0.45em;
|
|
border-radius: var(--r-sm);
|
|
}
|
|
|
|
.tag {
|
|
font-size: 0.65rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.06em;
|
|
padding: 0.05em 0.4em;
|
|
border-radius: var(--r-sm);
|
|
background: var(--c-bg-muted);
|
|
color: var(--c-fg-subtle);
|
|
border: 1px solid var(--c-border);
|
|
}
|
|
|
|
.arrow {
|
|
margin-left: auto;
|
|
display: inline-flex;
|
|
color: var(--c-fg-subtle);
|
|
opacity: 0;
|
|
transform: translateX(-4px);
|
|
transition:
|
|
opacity 180ms var(--ease),
|
|
transform 180ms var(--ease),
|
|
color 180ms var(--ease);
|
|
}
|
|
|
|
.card:hover .arrow {
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
color: var(--c-accent);
|
|
}
|
|
|
|
.desc {
|
|
margin: 0;
|
|
font-size: 0.875rem;
|
|
color: var(--c-fg-muted);
|
|
line-height: 1.55;
|
|
}
|
|
|
|
.factories {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.35rem;
|
|
margin-top: 0.4rem;
|
|
}
|
|
|
|
.factories code {
|
|
font-family: var(--font-mono);
|
|
font-size: 0.72rem;
|
|
padding: 0.1em 0.45em;
|
|
background: transparent;
|
|
color: var(--c-fg-subtle);
|
|
border: 1px solid var(--c-border);
|
|
border-radius: var(--r-sm);
|
|
white-space: nowrap;
|
|
transition:
|
|
color 180ms var(--ease),
|
|
border-color 180ms var(--ease);
|
|
}
|
|
|
|
.card:hover .factories code {
|
|
color: var(--c-fg-muted);
|
|
border-color: var(--c-border-strong);
|
|
}
|
|
</style>
|