Use the theme's cards, buttons, inputs and filter buttons everywhere
Build & Deploy / deploy (push) Successful in 2m48s
Build & Deploy / deploy (push) Successful in 2m48s
Every hand-written card, button, input, the profiler's filter buttons, the upload area, the chat bubbles, the nav links and the shortcut key now use Weircon-wind components. The theme is imported into Tailwind's components layer so utilities on the same element still apply. Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
@@ -19,8 +19,8 @@ const t = lang === 'en' ? {
|
|||||||
<form id="chat-form" class="mt-6 flex gap-3" data-thinking={t.thinking} data-offline={t.offline} data-unreachable={t.unreachable}>
|
<form id="chat-form" class="mt-6 flex gap-3" data-thinking={t.thinking} data-offline={t.offline} data-unreachable={t.unreachable}>
|
||||||
<input id="chat-input" type="text" required maxlength="500" autocomplete="off"
|
<input id="chat-input" type="text" required maxlength="500" autocomplete="off"
|
||||||
placeholder={t.placeholder}
|
placeholder={t.placeholder}
|
||||||
class="flex-1 rounded-xl border border-border bg-surface/60 px-4 py-2.5 outline-none focus:border-accent" />
|
class="flex-1 wt-input wt-input--lg" />
|
||||||
<button type="submit" class="rounded-xl bg-accent px-5 py-2.5 font-medium text-bg transition-transform hover:-translate-y-0.5">Send</button>
|
<button type="submit" class="wt-btn wt-btn--primary wt-btn--lg">Send</button>
|
||||||
</form>
|
</form>
|
||||||
<p class="mt-3 text-xs text-muted/80">{t.disclaimer}</p>
|
<p class="mt-3 text-xs text-muted/80">{t.disclaimer}</p>
|
||||||
|
|
||||||
@@ -49,8 +49,7 @@ const t = lang === 'en' ? {
|
|||||||
function bubble(role, text) {
|
function bubble(role, text) {
|
||||||
var log = document.getElementById('chat-log');
|
var log = document.getElementById('chat-log');
|
||||||
var d = document.createElement('div');
|
var d = document.createElement('div');
|
||||||
d.className = 'rounded-2xl border border-border p-4 text-sm whitespace-pre-wrap ' +
|
d.className = 'wt-card text-sm whitespace-pre-wrap ' + (role === 'user' ? 'wt-card--alt ml-8' : 'mr-8');
|
||||||
(role === 'user' ? 'bg-surface-2 ml-8' : 'bg-surface/60 mr-8');
|
|
||||||
if (role === 'user') d.textContent = text; else d.innerHTML = linkify(text);
|
if (role === 'user') d.textContent = text; else d.innerHTML = linkify(text);
|
||||||
log.appendChild(d);
|
log.appendChild(d);
|
||||||
d.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
d.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ const en = lang === 'en';
|
|||||||
aria-live="polite"
|
aria-live="polite"
|
||||||
aria-label={en ? 'Cookie notice' : 'Cookie-besked'}
|
aria-label={en ? 'Cookie notice' : 'Cookie-besked'}
|
||||||
>
|
>
|
||||||
<div class="mx-auto flex max-w-3xl flex-col gap-3 rounded-2xl border border-border bg-surface/95 p-4 shadow-xl backdrop-blur sm:flex-row sm:items-center sm:justify-between">
|
<div class="mx-auto flex max-w-3xl flex-col gap-3 wt-card wt-card--raised sm:flex-row sm:items-center sm:justify-between">
|
||||||
<p class="text-sm text-muted">
|
<p class="text-sm text-muted">
|
||||||
{en ? 'This site uses cookies to improve your experience and keep anonymous visitor statistics. By using the site you accept this.' : 'Denne side bruger cookies til at forbedre din oplevelse og lave anonym statistik over besøg. Ved at bruge siden accepterer du det.'}
|
{en ? 'This site uses cookies to improve your experience and keep anonymous visitor statistics. By using the site you accept this.' : 'Denne side bruger cookies til at forbedre din oplevelse og lave anonym statistik over besøg. Ved at bruge siden accepterer du det.'}
|
||||||
<a href="/cookies" class="text-accent underline">{en ? 'Read more (Danish)' : 'Læs mere'}</a>.
|
<a href="/cookies" class="text-accent underline">{en ? 'Read more (Danish)' : 'Læs mere'}</a>.
|
||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
id="cookie-ok"
|
id="cookie-ok"
|
||||||
class="shrink-0 self-start rounded-xl bg-accent px-5 py-2 text-sm font-medium text-bg transition-transform hover:-translate-y-0.5 sm:self-auto"
|
class="shrink-0 self-start wt-btn wt-btn--primary sm:self-auto"
|
||||||
>OK</button>
|
>OK</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,10 +17,8 @@ const isActive = (href: string) => (href === '/' || href === '/en' ? path === hr
|
|||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
href={item.href}
|
href={item.href}
|
||||||
class:list={[
|
class="wt-nav-link"
|
||||||
'rounded-lg px-3 py-1.5 transition-colors hover:text-text',
|
aria-current={isActive(item.href) ? 'page' : undefined}
|
||||||
isActive(item.href) ? 'text-text bg-surface-2' : 'text-muted',
|
|
||||||
]}
|
|
||||||
>{item.label}</a>
|
>{item.label}</a>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ interface Props { href: string; title: string; date: Date; description?: string;
|
|||||||
const { href, title, date, description, tags = [] } = Astro.props;
|
const { href, title, date, description, tags = [] } = Astro.props;
|
||||||
const d = date.toLocaleDateString('da-DK', { year: 'numeric', month: 'long', day: 'numeric' });
|
const d = date.toLocaleDateString('da-DK', { year: 'numeric', month: 'long', day: 'numeric' });
|
||||||
---
|
---
|
||||||
<article class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent/50">
|
<article class="group wt-card wt-card--hover">
|
||||||
<a href={href} class="block">
|
<a href={href} class="block">
|
||||||
<div class="text-xs text-muted">{d}</div>
|
<div class="text-xs text-muted">{d}</div>
|
||||||
<h3 class="mt-1 text-lg font-semibold tracking-tight group-hover:text-accent">{title}</h3>
|
<h3 class="mt-1 text-lg font-semibold tracking-tight group-hover:text-accent">{title}</h3>
|
||||||
|
|||||||
+1
-1
@@ -5,6 +5,6 @@ import Base from '../layouts/Base.astro';
|
|||||||
<div class="py-20 text-center">
|
<div class="py-20 text-center">
|
||||||
<h1 class="text-6xl font-bold tracking-tight">404</h1>
|
<h1 class="text-6xl font-bold tracking-tight">404</h1>
|
||||||
<p class="mt-4 text-muted">Siden findes ikke.</p>
|
<p class="mt-4 text-muted">Siden findes ikke.</p>
|
||||||
<a href="/" class="mt-8 inline-block rounded-xl bg-accent px-5 py-2.5 font-medium text-bg">Til forsiden</a>
|
<a href="/" class="mt-8 wt-btn wt-btn--primary wt-btn--lg">Til forsiden</a>
|
||||||
</div>
|
</div>
|
||||||
</Base>
|
</Base>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const stack = [
|
|||||||
ingen tredjeparts-fonts, ingen eksterne trackere.. bare en statisk side der gør hvad den får besked på.
|
ingen tredjeparts-fonts, ingen eksterne trackere.. bare en statisk side der gør hvad den får besked på.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="mt-8 overflow-hidden rounded-2xl border border-border">
|
<div class="mt-8 wt-card wt-card--flush">
|
||||||
<table class="w-full text-sm">
|
<table class="w-full text-sm">
|
||||||
<tbody>
|
<tbody>
|
||||||
{stack.map((row) => (
|
{stack.map((row) => (
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import Base from '../layouts/Base.astro';
|
|||||||
|
|
||||||
<h2 class="mt-10 text-2xl font-bold tracking-tight">Hvad bruger vi dem til?</h2>
|
<h2 class="mt-10 text-2xl font-bold tracking-tight">Hvad bruger vi dem til?</h2>
|
||||||
<div class="mt-5 grid gap-4">
|
<div class="mt-5 grid gap-4">
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<h3 class="font-semibold tracking-tight">Statistik & analyse</h3>
|
<h3 class="font-semibold tracking-tight">Statistik & analyse</h3>
|
||||||
<p class="mt-2 text-sm text-muted">
|
<p class="mt-2 text-sm text-muted">
|
||||||
Jeg bruger <strong class="text-text">Matomo</strong> til at se hvor mange der besøger siden,
|
Jeg bruger <strong class="text-text">Matomo</strong> til at se hvor mange der besøger siden,
|
||||||
@@ -25,7 +25,7 @@ import Base from '../layouts/Base.astro';
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<h3 class="font-semibold tracking-tight">Funktionelt</h3>
|
<h3 class="font-semibold tracking-tight">Funktionelt</h3>
|
||||||
<p class="mt-2 text-sm text-muted">
|
<p class="mt-2 text-sm text-muted">
|
||||||
Husker dine valg på siden. Det er ikke sporing, og det forlader aldrig din browser.
|
Husker dine valg på siden. Det er ikke sporing, og det forlader aldrig din browser.
|
||||||
|
|||||||
+7
-7
@@ -126,7 +126,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Erhvervserfaring</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Erhvervserfaring</h2>
|
||||||
<div class="mt-4 space-y-4">
|
<div class="mt-4 space-y-4">
|
||||||
{erhverv.map((e) => (
|
{erhverv.map((e) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<h3 class="font-semibold">{e.org} <span class="font-normal text-muted">· {e.sted}</span></h3>
|
<h3 class="font-semibold">{e.org} <span class="font-normal text-muted">· {e.sted}</span></h3>
|
||||||
<div class="mt-3 space-y-3">
|
<div class="mt-3 space-y-3">
|
||||||
{e.roller.map((r) => (
|
{e.roller.map((r) => (
|
||||||
@@ -150,7 +150,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Uddannelse</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Uddannelse</h2>
|
||||||
<div class="mt-4 space-y-4">
|
<div class="mt-4 space-y-4">
|
||||||
{uddannelse.map((u) => (
|
{uddannelse.map((u) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
||||||
<h3 class="font-semibold">{u.hvad}</h3><span class="text-xs text-muted">{u.naar}</span>
|
<h3 class="font-semibold">{u.hvad}</h3><span class="text-xs text-muted">{u.naar}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -165,7 +165,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Licenser</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Licenser</h2>
|
||||||
<div class="mt-4 space-y-4">
|
<div class="mt-4 space-y-4">
|
||||||
{licenser.map((l) => (
|
{licenser.map((l) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
||||||
<h3 class="font-semibold">{l.hvad}</h3><span class="text-xs text-muted">{l.naar}</span>
|
<h3 class="font-semibold">{l.hvad}</h3><span class="text-xs text-muted">{l.naar}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -178,7 +178,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
|
|||||||
|
|
||||||
<section class="mt-10">
|
<section class="mt-10">
|
||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Publikationer</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Publikationer</h2>
|
||||||
<div class="mt-4 rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="mt-4 wt-card">
|
||||||
<a href="https://arxiv.org/abs/2310.00999" target="_blank" rel="noopener" class="font-medium hover:text-accent">
|
<a href="https://arxiv.org/abs/2310.00999" target="_blank" rel="noopener" class="font-medium hover:text-accent">
|
||||||
CGAAL: Distributed On-The-Fly ATL Model Checker with Heuristics
|
CGAAL: Distributed On-The-Fly ATL Model Checker with Heuristics
|
||||||
</a>
|
</a>
|
||||||
@@ -193,7 +193,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Frivilligt arbejde</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Frivilligt arbejde</h2>
|
||||||
<div class="mt-4 space-y-4">
|
<div class="mt-4 space-y-4">
|
||||||
{frivilligt.map((f) => (
|
{frivilligt.map((f) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
||||||
<h3 class="font-semibold">{f.hvad}</h3><span class="text-xs text-muted">{f.naar}</span>
|
<h3 class="font-semibold">{f.hvad}</h3><span class="text-xs text-muted">{f.naar}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -217,7 +217,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
|
|||||||
<div>
|
<div>
|
||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Sprog</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Sprog</h2>
|
||||||
<ul class="mt-4 space-y-2 text-sm">
|
<ul class="mt-4 space-y-2 text-sm">
|
||||||
{sprog.map((s) => <li class="rounded-xl border border-border bg-surface/60 px-3 py-2">{s}</li>)}
|
{sprog.map((s) => <li class="wt-card wt-card--compact">{s}</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
<h2 class="mt-8 text-sm font-semibold uppercase tracking-widest text-accent">Interesser</h2>
|
<h2 class="mt-8 text-sm font-semibold uppercase tracking-widest text-accent">Interesser</h2>
|
||||||
<p class="mt-4 text-sm text-muted">
|
<p class="mt-4 text-sm text-muted">
|
||||||
@@ -236,7 +236,7 @@ const sprog = ['Dansk (modersmål)', 'Engelsk (flydende i tale og skrift)'];
|
|||||||
|
|
||||||
<section class="mt-10">
|
<section class="mt-10">
|
||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Natur og jagt</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Natur og jagt</h2>
|
||||||
<div class="mt-4 rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="mt-4 wt-card">
|
||||||
<p class="text-muted">
|
<p class="text-muted">
|
||||||
Jeg har jagttegn, men jagten er mest anledningen. Det jeg tager ud efter, er at stå op
|
Jeg har jagttegn, men jagten er mest anledningen. Det jeg tager ud efter, er at stå op
|
||||||
længe før resten af landet og træde ud i den stilhed, der kun findes tidligt om morgenen,
|
længe før resten af landet og træde ud i den stilhed, der kun findes tidligt om morgenen,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ const skills = [
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Experience</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Experience</h2>
|
||||||
<div class="mt-4 space-y-4">
|
<div class="mt-4 space-y-4">
|
||||||
{work.map((e) => (
|
{work.map((e) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<h3 class="font-semibold">{e.org} <span class="font-normal text-muted">· {e.place}</span></h3>
|
<h3 class="font-semibold">{e.org} <span class="font-normal text-muted">· {e.place}</span></h3>
|
||||||
<div class="mt-3 space-y-3">
|
<div class="mt-3 space-y-3">
|
||||||
{e.roles.map((r) => (
|
{e.roles.map((r) => (
|
||||||
@@ -122,7 +122,7 @@ const skills = [
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Education</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Education</h2>
|
||||||
<div class="mt-4 space-y-4">
|
<div class="mt-4 space-y-4">
|
||||||
{education.map((u) => (
|
{education.map((u) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
||||||
<h3 class="font-semibold">{u.what}</h3><span class="text-xs text-muted">{u.when}</span>
|
<h3 class="font-semibold">{u.what}</h3><span class="text-xs text-muted">{u.when}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -135,7 +135,7 @@ const skills = [
|
|||||||
|
|
||||||
<section class="mt-10">
|
<section class="mt-10">
|
||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Publication</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Publication</h2>
|
||||||
<div class="mt-4 rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="mt-4 wt-card">
|
||||||
<a href="https://arxiv.org/abs/2310.00999" target="_blank" rel="noopener" class="font-medium hover:text-accent">
|
<a href="https://arxiv.org/abs/2310.00999" target="_blank" rel="noopener" class="font-medium hover:text-accent">
|
||||||
CGAAL: Distributed On-The-Fly ATL Model Checker with Heuristics
|
CGAAL: Distributed On-The-Fly ATL Model Checker with Heuristics
|
||||||
</a>
|
</a>
|
||||||
@@ -164,8 +164,8 @@ const skills = [
|
|||||||
<div>
|
<div>
|
||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Languages</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Languages</h2>
|
||||||
<ul class="mt-4 space-y-2 text-sm">
|
<ul class="mt-4 space-y-2 text-sm">
|
||||||
<li class="rounded-xl border border-border bg-surface/60 px-3 py-2">Danish (native)</li>
|
<li class="wt-card wt-card--compact">Danish (native)</li>
|
||||||
<li class="rounded-xl border border-border bg-surface/60 px-3 py-2">English (fluent, spoken and written)</li>
|
<li class="wt-card wt-card--compact">English (fluent, spoken and written)</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ const faqs = [
|
|||||||
the air as a radio amateur (OZ0AGW).
|
the air as a radio amateur (OZ0AGW).
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-7 flex flex-wrap gap-3">
|
<div class="mt-7 flex flex-wrap gap-3">
|
||||||
<a href="/en/cv" class="rounded-xl bg-accent px-5 py-2.5 font-medium text-bg transition-transform hover:-translate-y-0.5">See my CV</a>
|
<a href="/en/cv" class="wt-btn wt-btn--primary wt-btn--lg">See my CV</a>
|
||||||
<a href="/en/chat" class="rounded-xl border border-border px-5 py-2.5 font-medium transition-colors hover:border-accent">Ask my CV</a>
|
<a href="/en/chat" class="wt-btn wt-btn--lg">Ask my CV</a>
|
||||||
<a href="/en/projects" class="rounded-xl border border-border px-5 py-2.5 font-medium transition-colors hover:border-accent">Projects</a>
|
<a href="/en/projects" class="wt-btn wt-btn--lg">Projects</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Image
|
<Image
|
||||||
@@ -60,7 +60,7 @@ const faqs = [
|
|||||||
|
|
||||||
<section class="mt-14 grid gap-4 sm:grid-cols-3">
|
<section class="mt-14 grid gap-4 sm:grid-cols-3">
|
||||||
{highlights.map((h) => (
|
{highlights.map((h) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<h2 class="font-semibold tracking-tight">{h.title}</h2>
|
<h2 class="font-semibold tracking-tight">{h.title}</h2>
|
||||||
<p class="mt-2 text-sm text-muted">{h.body}</p>
|
<p class="mt-2 text-sm text-muted">{h.body}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -76,20 +76,20 @@ const faqs = [
|
|||||||
{ href: '/ubl', title: 'UBL check (Danish)', desc: 'Drop in an e-invoice and get its profile, syntax and EN 16931 status decoded. It all runs in the browser, the file never leaves your machine.' },
|
{ href: '/ubl', title: 'UBL check (Danish)', desc: 'Drop in an e-invoice and get its profile, syntax and EN 16931 status decoded. It all runs in the browser, the file never leaves your machine.' },
|
||||||
{ href: '/en/projects', title: 'Projects', desc: 'Tools I maintain and publish on the AUR, Homebrew and Scoop.' },
|
{ href: '/en/projects', title: 'Projects', desc: 'Tools I maintain and publish on the AUR, Homebrew and Scoop.' },
|
||||||
].map((c) => (
|
].map((c) => (
|
||||||
<a href={c.href} class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent">
|
<a href={c.href} class="group wt-card wt-card--hover">
|
||||||
<h3 class="font-semibold tracking-tight group-hover:text-accent">{c.title} →</h3>
|
<h3 class="font-semibold tracking-tight group-hover:text-accent">{c.title} →</h3>
|
||||||
<p class="mt-2 text-sm text-muted">{c.desc}</p>
|
<p class="mt-2 text-sm text-muted">{c.desc}</p>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-3 text-xs text-muted/80">Pro tip: press <kbd class="rounded border border-border bg-surface-2 px-1.5 py-0.5 font-mono text-[0.7rem]">Ctrl/⌘ K</kbd> to jump anywhere, or run <code class="rounded bg-surface-2 px-1.5 py-0.5">curl asger.weirsøe.dk</code> in a terminal.</p>
|
<p class="mt-3 text-xs text-muted/80">Pro tip: press <kbd class="wt-kbd">Ctrl/⌘ K</kbd> to jump anywhere, or run <code class="rounded bg-surface-2 px-1.5 py-0.5">curl asger.weirsøe.dk</code> in a terminal.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="mt-16">
|
<section class="mt-16">
|
||||||
<h2 class="text-2xl font-bold tracking-tight">Frequently asked questions</h2>
|
<h2 class="text-2xl font-bold tracking-tight">Frequently asked questions</h2>
|
||||||
<div class="mt-5 grid gap-3">
|
<div class="mt-5 grid gap-3">
|
||||||
{faqs.map((f) => (
|
{faqs.map((f) => (
|
||||||
<details class="group rounded-2xl border border-border bg-surface/60 p-5">
|
<details class="group wt-card">
|
||||||
<summary class="cursor-pointer list-none font-semibold tracking-tight marker:hidden">{f.q}</summary>
|
<summary class="cursor-pointer list-none font-semibold tracking-tight marker:hidden">{f.q}</summary>
|
||||||
<p class="mt-3 text-sm text-muted">{f.a}</p>
|
<p class="mt-3 text-sm text-muted">{f.a}</p>
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const ld = collectionPage({
|
|||||||
<div class="mt-8 grid gap-4 sm:grid-cols-2">
|
<div class="mt-8 grid gap-4 sm:grid-cols-2">
|
||||||
{sider.map((p) => (
|
{sider.map((p) => (
|
||||||
<a href={`/en/projects/${p.id.replace(/^en\//, '')}`}
|
<a href={`/en/projects/${p.id.replace(/^en\//, '')}`}
|
||||||
class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent/50">
|
class="group wt-card wt-card--hover">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h3 class="font-semibold tracking-tight group-hover:text-accent">{p.data.title}</h3>
|
<h3 class="font-semibold tracking-tight group-hover:text-accent">{p.data.title}</h3>
|
||||||
{p.data.aur.length > 0 && <span class="text-xs text-muted">AUR</span>}
|
{p.data.aur.length > 0 && <span class="text-xs text-muted">AUR</span>}
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ const jsonLd = [profilePage, faqPage(faqs)];
|
|||||||
Proxmox-homelab, roder med AI-projekter og går på luften som radioamatør (OZ0AGW).
|
Proxmox-homelab, roder med AI-projekter og går på luften som radioamatør (OZ0AGW).
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-7 flex flex-wrap gap-3">
|
<div class="mt-7 flex flex-wrap gap-3">
|
||||||
<a href="/cv" class="rounded-xl bg-accent px-5 py-2.5 font-medium text-bg transition-transform hover:-translate-y-0.5">Se mit CV</a>
|
<a href="/cv" class="wt-btn wt-btn--primary wt-btn--lg">Se mit CV</a>
|
||||||
<a href="/projekter" class="rounded-xl border border-border px-5 py-2.5 font-medium transition-colors hover:border-accent">Projekter</a>
|
<a href="/projekter" class="wt-btn wt-btn--lg">Projekter</a>
|
||||||
<a href="/blog" class="rounded-xl border border-border px-5 py-2.5 font-medium transition-colors hover:border-accent">Blog</a>
|
<a href="/blog" class="wt-btn wt-btn--lg">Blog</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Image
|
<Image
|
||||||
@@ -73,7 +73,7 @@ const jsonLd = [profilePage, faqPage(faqs)];
|
|||||||
|
|
||||||
<section class="mt-14 grid gap-4 sm:grid-cols-3">
|
<section class="mt-14 grid gap-4 sm:grid-cols-3">
|
||||||
{highlights.map((h) => (
|
{highlights.map((h) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<h2 class="font-semibold tracking-tight">{h.title}</h2>
|
<h2 class="font-semibold tracking-tight">{h.title}</h2>
|
||||||
<p class="mt-2 text-sm text-muted">{h.body}</p>
|
<p class="mt-2 text-sm text-muted">{h.body}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,20 +91,20 @@ const jsonLd = [profilePage, faqPage(faqs)];
|
|||||||
{ href: '/profiler', title: 'Profil-opslag', desc: 'Søgbart opslag over Nemhandel OIOUBL- og Peppol BIS/PINT-profiler: id\'er, dokumenter og typisk brug.' },
|
{ href: '/profiler', title: 'Profil-opslag', desc: 'Søgbart opslag over Nemhandel OIOUBL- og Peppol BIS/PINT-profiler: id\'er, dokumenter og typisk brug.' },
|
||||||
{ href: '/ubl', title: 'UBL-tjek', desc: 'Træk en faktura ind og få profil, syntaks og EN 16931-status afkodet. Alt sker i browseren, filen forlader aldrig din maskine.' },
|
{ href: '/ubl', title: 'UBL-tjek', desc: 'Træk en faktura ind og få profil, syntaks og EN 16931-status afkodet. Alt sker i browseren, filen forlader aldrig din maskine.' },
|
||||||
].map((c) => (
|
].map((c) => (
|
||||||
<a href={c.href} class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent">
|
<a href={c.href} class="group wt-card wt-card--hover">
|
||||||
<h3 class="font-semibold tracking-tight group-hover:text-accent">{c.title} →</h3>
|
<h3 class="font-semibold tracking-tight group-hover:text-accent">{c.title} →</h3>
|
||||||
<p class="mt-2 text-sm text-muted">{c.desc}</p>
|
<p class="mt-2 text-sm text-muted">{c.desc}</p>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-3 text-xs text-muted/80">Pro-tip: tryk <kbd class="rounded border border-border bg-surface-2 px-1.5 py-0.5 font-mono text-[0.7rem]">Ctrl/⌘ K</kbd> og hop direkte til alt, eller <code class="rounded bg-surface-2 px-1.5 py-0.5">curl asger.weirsøe.dk</code> i en terminal.</p>
|
<p class="mt-3 text-xs text-muted/80">Pro-tip: tryk <kbd class="wt-kbd">Ctrl/⌘ K</kbd> og hop direkte til alt, eller <code class="rounded bg-surface-2 px-1.5 py-0.5">curl asger.weirsøe.dk</code> i en terminal.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="mt-16">
|
<section class="mt-16">
|
||||||
<h2 class="text-2xl font-bold tracking-tight">Ofte stillede spørgsmål</h2>
|
<h2 class="text-2xl font-bold tracking-tight">Ofte stillede spørgsmål</h2>
|
||||||
<div class="mt-5 grid gap-3">
|
<div class="mt-5 grid gap-3">
|
||||||
{faqs.map((f) => (
|
{faqs.map((f) => (
|
||||||
<details class="group rounded-2xl border border-border bg-surface/60 p-5">
|
<details class="group wt-card">
|
||||||
<summary class="cursor-pointer list-none font-semibold tracking-tight marker:hidden">
|
<summary class="cursor-pointer list-none font-semibold tracking-tight marker:hidden">
|
||||||
{f.q}
|
{f.q}
|
||||||
</summary>
|
</summary>
|
||||||
|
|||||||
+11
-12
@@ -12,15 +12,15 @@ import Base from '../layouts/Base.astro';
|
|||||||
<form id="pep-form" class="mt-8 flex gap-3">
|
<form id="pep-form" class="mt-8 flex gap-3">
|
||||||
<input id="pep-cvr" type="text" inputmode="numeric" pattern="[0-9]{8}" maxlength="8" required
|
<input id="pep-cvr" type="text" inputmode="numeric" pattern="[0-9]{8}" maxlength="8" required
|
||||||
placeholder="CVR (8 cifre)" autocomplete="off"
|
placeholder="CVR (8 cifre)" autocomplete="off"
|
||||||
class="w-44 rounded-xl border border-border bg-surface/60 px-4 py-2.5 outline-none focus:border-accent" />
|
class="w-44 wt-input wt-input--lg" />
|
||||||
<button type="submit" class="rounded-xl bg-accent px-5 py-2.5 font-medium text-bg transition-transform hover:-translate-y-0.5">Slå op</button>
|
<button type="submit" class="wt-btn wt-btn--primary wt-btn--lg">Slå op</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div id="pep-result" class="mt-8" hidden>
|
<div id="pep-result" class="mt-8" hidden>
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-5">
|
<div class="wt-card">
|
||||||
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
||||||
<h2 id="pep-name" class="text-xl font-semibold tracking-tight"></h2>
|
<h2 id="pep-name" class="text-xl font-semibold tracking-tight"></h2>
|
||||||
<span id="pep-badge" class="rounded-full px-3 py-1 text-sm font-medium"></span>
|
<span id="pep-badge" class="wt-tag"></span>
|
||||||
</div>
|
</div>
|
||||||
<p id="pep-cvr-line" class="mt-1 text-sm text-muted"></p>
|
<p id="pep-cvr-line" class="mt-1 text-sm text-muted"></p>
|
||||||
<div id="pep-caps" class="mt-4"></div>
|
<div id="pep-caps" class="mt-4"></div>
|
||||||
@@ -46,29 +46,29 @@ import Base from '../layouts/Base.astro';
|
|||||||
};
|
};
|
||||||
async function loadPeppol(cvr) {
|
async function loadPeppol(cvr) {
|
||||||
var box = document.getElementById('peppol-net'); box.hidden = false;
|
var box = document.getElementById('peppol-net'); box.hidden = false;
|
||||||
box.innerHTML = '<div class="rounded-2xl border border-border bg-surface/60 p-5"><p class="text-sm text-muted">Slår op i Peppol-netværket…</p></div>';
|
box.innerHTML = '<div class="wt-card"><p class="text-sm text-muted">Slår op i Peppol-netværket…</p></div>';
|
||||||
try {
|
try {
|
||||||
var r = await fetch('/api/peppol/smp/' + encodeURIComponent(cvr));
|
var r = await fetch('/api/peppol/smp/' + encodeURIComponent(cvr));
|
||||||
var d = await r.json();
|
var d = await r.json();
|
||||||
if (!r.ok) { box.innerHTML = '<div class="rounded-2xl border border-border bg-surface/60 p-5"><p class="text-sm text-muted">Peppol-opslag ikke tilgængeligt lige nu.</p></div>'; return; }
|
if (!r.ok) { box.innerHTML = '<div class="wt-card"><p class="text-sm text-muted">Peppol-opslag ikke tilgængeligt lige nu.</p></div>'; return; }
|
||||||
if (!d.on_peppol) {
|
if (!d.on_peppol) {
|
||||||
box.innerHTML = '<div class="rounded-2xl border border-border bg-surface/60 p-5"><div class="flex items-baseline justify-between gap-2"><h2 class="text-xl font-semibold tracking-tight">Peppol-netværk</h2><span class="wt-tag wt-muted">Ikke fundet</span></div><p class="mt-2 text-sm text-muted">Virksomheden blev ikke fundet i Peppol Directory via CVR-opslag (kan stadig være på Peppol under et andet identifikator-scheme).</p></div>';
|
box.innerHTML = '<div class="wt-card"><div class="flex items-baseline justify-between gap-2"><h2 class="text-xl font-semibold tracking-tight">Peppol-netværk</h2><span class="wt-tag wt-muted">Ikke fundet</span></div><p class="mt-2 text-sm text-muted">Virksomheden blev ikke fundet i Peppol Directory via CVR-opslag (kan stadig være på Peppol under et andet identifikator-scheme).</p></div>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var docs = (d.doctypes || []).map(function (dt) {
|
var docs = (d.doctypes || []).map(function (dt) {
|
||||||
var label = PROF[dt.customization] || dt.customization;
|
var label = PROF[dt.customization] || dt.customization;
|
||||||
return '<span class="wt-tag">' + esc(dt.document) + ' · ' + esc(label) + '</span>';
|
return '<span class="wt-tag">' + esc(dt.document) + ' · ' + esc(label) + '</span>';
|
||||||
}).join('');
|
}).join('');
|
||||||
box.innerHTML = '<div class="rounded-2xl border border-border bg-surface/60 p-5">' +
|
box.innerHTML = '<div class="wt-card">' +
|
||||||
'<div class="flex flex-wrap items-baseline justify-between gap-2"><h2 class="text-xl font-semibold tracking-tight">Peppol-netværk</h2>' +
|
'<div class="flex flex-wrap items-baseline justify-between gap-2"><h2 class="text-xl font-semibold tracking-tight">Peppol-netværk</h2>' +
|
||||||
'<span class="rounded-full bg-accent/15 px-3 py-1 text-sm font-medium text-accent">På Peppol</span></div>' +
|
'<span class="wt-tag wt-tag--accent">På Peppol</span></div>' +
|
||||||
'<p class="mt-1 text-sm text-muted">' + esc(d.name || '') + (d.country ? ' · ' + esc(d.country) : '') +
|
'<p class="mt-1 text-sm text-muted">' + esc(d.name || '') + (d.country ? ' · ' + esc(d.country) : '') +
|
||||||
' · <span class="font-mono text-xs">' + esc(d.participant_id || '') + '</span>' + (d.reg_date ? ' · reg. ' + esc(d.reg_date) : '') + '</p>' +
|
' · <span class="font-mono text-xs">' + esc(d.participant_id || '') + '</span>' + (d.reg_date ? ' · reg. ' + esc(d.reg_date) : '') + '</p>' +
|
||||||
'<p class="mt-4 text-xs font-semibold uppercase tracking-widest text-accent">Kan modtage</p>' +
|
'<p class="mt-4 text-xs font-semibold uppercase tracking-widest text-accent">Kan modtage</p>' +
|
||||||
'<div class="mt-2 flex flex-wrap gap-2">' + (docs || '<span class="text-sm text-muted">ingen dokumenttyper</span>') + '</div>' +
|
'<div class="mt-2 flex flex-wrap gap-2">' + (docs || '<span class="text-sm text-muted">ingen dokumenttyper</span>') + '</div>' +
|
||||||
'<p class="mt-3 text-xs text-muted/80">Live fra Peppol Directory via egen proxy, intet gemt.</p></div>';
|
'<p class="mt-3 text-xs text-muted/80">Live fra Peppol Directory via egen proxy, intet gemt.</p></div>';
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
box.innerHTML = '<div class="rounded-2xl border border-border bg-surface/60 p-5"><p class="text-sm text-muted">Kunne ikke nå Peppol-opslaget.</p></div>';
|
box.innerHTML = '<div class="wt-card"><p class="text-sm text-muted">Kunne ikke nå Peppol-opslaget.</p></div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form.addEventListener('submit', async function (e) {
|
form.addEventListener('submit', async function (e) {
|
||||||
@@ -86,8 +86,7 @@ import Base from '../layouts/Base.astro';
|
|||||||
document.getElementById('pep-cvr-line').textContent = 'CVR ' + data.cvr;
|
document.getElementById('pep-cvr-line').textContent = 'CVR ' + data.cvr;
|
||||||
var badge = document.getElementById('pep-badge');
|
var badge = document.getElementById('pep-badge');
|
||||||
badge.textContent = data.registered ? 'Registreret i NemHandel' : 'Ikke registreret';
|
badge.textContent = data.registered ? 'Registreret i NemHandel' : 'Ikke registreret';
|
||||||
badge.className = 'rounded-full px-3 py-1 text-sm font-medium ' +
|
badge.className = 'wt-tag ' + (data.registered ? 'wt-tag--accent' : 'wt-muted');
|
||||||
(data.registered ? 'bg-accent/15 text-accent' : 'border border-border text-muted');
|
|
||||||
var caps = document.getElementById('pep-caps');
|
var caps = document.getElementById('pep-caps');
|
||||||
if (data.registered && (data.profiles.length || data.networks.length)) {
|
if (data.registered && (data.profiles.length || data.networks.length)) {
|
||||||
caps.innerHTML =
|
caps.innerHTML =
|
||||||
|
|||||||
+2
-2
@@ -48,7 +48,7 @@ const updated = today.toLocaleDateString('da-DK', { year: 'numeric', month: 'lon
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Lige nu</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Lige nu</h2>
|
||||||
<ul class="mt-4 space-y-3">
|
<ul class="mt-4 space-y-3">
|
||||||
{focus.map((f) => (
|
{focus.map((f) => (
|
||||||
<li class="rounded-2xl border border-border bg-surface/60 p-4 text-sm">{f}</li>
|
<li class="wt-card text-sm">{f}</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
@@ -57,7 +57,7 @@ const updated = today.toLocaleDateString('da-DK', { year: 'numeric', month: 'lon
|
|||||||
<section class="mt-10">
|
<section class="mt-10">
|
||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Git-aktivitet</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">Git-aktivitet</h2>
|
||||||
<p class="mt-2 text-sm text-muted">{total} bidrag i mit eget Gitea det seneste år, de seneste {WEEKS} uger:</p>
|
<p class="mt-2 text-sm text-muted">{total} bidrag i mit eget Gitea det seneste år, de seneste {WEEKS} uger:</p>
|
||||||
<div class="mt-4 overflow-x-auto rounded-2xl border border-border bg-surface/60 p-4">
|
<div class="mt-4 overflow-x-auto wt-card">
|
||||||
<div class="heatmap" role="img" aria-label="Aktivitets-heatmap over git-bidrag">
|
<div class="heatmap" role="img" aria-label="Aktivitets-heatmap over git-bidrag">
|
||||||
{weeks.map((w) => (
|
{weeks.map((w) => (
|
||||||
<div class="hm-col">
|
<div class="hm-col">
|
||||||
|
|||||||
@@ -51,22 +51,22 @@ const kilde = (p: (typeof profiles)[number]) => {
|
|||||||
placeholder="Søg profil, id, dokument…"
|
placeholder="Søg profil, id, dokument…"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
aria-label="Søg profiler"
|
aria-label="Søg profiler"
|
||||||
class="w-full rounded-xl border border-border bg-surface/60 py-2.5 pl-9 pr-4 outline-none focus:border-accent"
|
class="w-full wt-input wt-input--lg pl-9"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span id="p-count" class="text-sm text-muted">{profiles.length} profiler</span>
|
<span id="p-count" class="text-sm text-muted">{profiles.length} profiler</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3 flex flex-wrap gap-2">
|
<div class="mt-3 flex flex-wrap gap-2">
|
||||||
<button type="button" class="p-chip" data-std="" aria-pressed="true">Alle</button>
|
<button type="button" class="wt-btn wt-btn--ghost wt-btn--sm" data-std="" aria-pressed="true">Alle</button>
|
||||||
{standarder.map((s) => <button type="button" class="p-chip" data-std={s} aria-pressed="false">{s}</button>)}
|
{standarder.map((s) => <button type="button" class="wt-btn wt-btn--ghost wt-btn--sm" data-std={s} aria-pressed="false">{s}</button>)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<span class="mr-2 text-xs text-muted">Nemhandelsregistrets kategori:</span>
|
<span class="mr-2 text-xs text-muted">Nemhandelsregistrets kategori:</span>
|
||||||
<span class="mt-1 inline-flex flex-wrap gap-2 align-middle">
|
<span class="mt-1 inline-flex flex-wrap gap-2 align-middle">
|
||||||
<button type="button" class="p-chip" data-kat="" aria-pressed="true">Alle</button>
|
<button type="button" class="wt-btn wt-btn--ghost wt-btn--sm" data-kat="" aria-pressed="true">Alle</button>
|
||||||
{kategorier.map((k) => <button type="button" class="p-chip" data-kat={k} aria-pressed="false">{k}</button>)}
|
{kategorier.map((k) => <button type="button" class="wt-btn wt-btn--ghost wt-btn--sm" data-kat={k} aria-pressed="false">{k}</button>)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ const kilde = (p: (typeof profiles)[number]) => {
|
|||||||
data-standard={p.standard}
|
data-standard={p.standard}
|
||||||
data-kategori={p.kategori ?? ''}
|
data-kategori={p.kategori ?? ''}
|
||||||
data-search={searchString(p)}
|
data-search={searchString(p)}
|
||||||
class="rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent/50"
|
class="wt-card wt-card--hover"
|
||||||
>
|
>
|
||||||
<div class="flex flex-wrap items-center gap-2">
|
<div class="flex flex-wrap items-center gap-2">
|
||||||
<span class="wt-tag wt-tag--accent">
|
<span class="wt-tag wt-tag--accent">
|
||||||
@@ -136,22 +136,6 @@ const kilde = (p: (typeof profiles)[number]) => {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<style is:inline>
|
<style is:inline>
|
||||||
.p-chip {
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
color: var(--color-muted);
|
|
||||||
border-radius: 0.6rem;
|
|
||||||
padding: 0.35rem 0.8rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
cursor: pointer;
|
|
||||||
background: transparent;
|
|
||||||
transition: color 0.15s, background-color 0.15s, border-color 0.15s;
|
|
||||||
}
|
|
||||||
.p-chip:hover { color: var(--color-text); }
|
|
||||||
.p-chip[aria-pressed="true"] {
|
|
||||||
background: var(--color-surface-2);
|
|
||||||
color: var(--color-text);
|
|
||||||
border-color: color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
|
|
||||||
}
|
|
||||||
.copy { transition: color 0.15s; }
|
.copy { transition: color 0.15s; }
|
||||||
.copy:hover { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }
|
.copy:hover { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }
|
||||||
</style>
|
</style>
|
||||||
@@ -160,8 +144,8 @@ const kilde = (p: (typeof profiles)[number]) => {
|
|||||||
(function () {
|
(function () {
|
||||||
var cards = [].slice.call(document.querySelectorAll('[data-profile]'));
|
var cards = [].slice.call(document.querySelectorAll('[data-profile]'));
|
||||||
var search = document.getElementById('p-search');
|
var search = document.getElementById('p-search');
|
||||||
var stdChips = [].slice.call(document.querySelectorAll('.p-chip[data-std]'));
|
var stdChips = [].slice.call(document.querySelectorAll('button[data-std]'));
|
||||||
var katChips = [].slice.call(document.querySelectorAll('.p-chip[data-kat]'));
|
var katChips = [].slice.call(document.querySelectorAll('button[data-kat]'));
|
||||||
var count = document.getElementById('p-count');
|
var count = document.getElementById('p-count');
|
||||||
var none = document.getElementById('p-none');
|
var none = document.getElementById('p-none');
|
||||||
var q = '', std = '', kat = '';
|
var q = '', std = '', kat = '';
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ try {
|
|||||||
<h1 class="text-4xl font-bold tracking-tight">Projekter</h1>
|
<h1 class="text-4xl font-bold tracking-tight">Projekter</h1>
|
||||||
<p class="mt-3 text-muted">Hentet live fra min <a class="text-accent hover:underline" href={`${SITE.giteaBase}/${SITE.giteaUser}`}>Gitea</a>.</p>
|
<p class="mt-3 text-muted">Hentet live fra min <a class="text-accent hover:underline" href={`${SITE.giteaBase}/${SITE.giteaUser}`}>Gitea</a>.</p>
|
||||||
|
|
||||||
{error && <p class="mt-8 rounded-xl border border-border bg-surface/60 p-5 text-muted">Kunne ikke hente repositories lige nu.</p>}
|
{error && <p class="mt-8 wt-card text-muted">Kunne ikke hente repositories lige nu.</p>}
|
||||||
|
|
||||||
<div class="mt-8 grid gap-4 sm:grid-cols-2">
|
<div class="mt-8 grid gap-4 sm:grid-cols-2">
|
||||||
{repos.map((r) => {
|
{repos.map((r) => {
|
||||||
const side = sider.get(r.name.toLowerCase());
|
const side = sider.get(r.name.toLowerCase());
|
||||||
return side ? (
|
return side ? (
|
||||||
<a href={`/projekter/${side.id}`}
|
<a href={`/projekter/${side.id}`}
|
||||||
class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent/50">
|
class="group wt-card wt-card--hover">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h3 class="font-semibold tracking-tight group-hover:text-accent">{side.data.title}</h3>
|
<h3 class="font-semibold tracking-tight group-hover:text-accent">{side.data.title}</h3>
|
||||||
{side.data.aur.length > 0 && <span class="text-xs text-muted">AUR</span>}
|
{side.data.aur.length > 0 && <span class="text-xs text-muted">AUR</span>}
|
||||||
@@ -55,7 +55,7 @@ try {
|
|||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
<a href={r.html_url} target="_blank" rel="noopener"
|
<a href={r.html_url} target="_blank" rel="noopener"
|
||||||
class="group rounded-2xl border border-border bg-surface/60 p-5 transition-colors hover:border-accent/50">
|
class="group wt-card wt-card--hover">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h3 class="font-semibold tracking-tight group-hover:text-accent">{r.name}</h3>
|
<h3 class="font-semibold tracking-tight group-hover:text-accent">{r.name}</h3>
|
||||||
{r.stars_count > 0 && <span class="text-xs text-muted">★ {r.stars_count}</span>}
|
{r.stars_count > 0 && <span class="text-xs text-muted">★ {r.stars_count}</span>}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const STATUS_URL = 'https://status.weircon.dk/status/weircon';
|
|||||||
Når man drifter ~50 containere selv, er det rart at vide hvornår man har smadret noget.
|
Når man drifter ~50 containere selv, er det rart at vide hvornår man har smadret noget.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="mt-8 overflow-hidden rounded-2xl border border-border bg-surface/60">
|
<div class="mt-8 wt-card wt-card--flush">
|
||||||
<iframe src={STATUS_URL} title="Uptime Kuma statusside" loading="lazy"
|
<iframe src={STATUS_URL} title="Uptime Kuma statusside" loading="lazy"
|
||||||
class="h-[70vh] w-full" style="border:0"></iframe>
|
class="h-[70vh] w-full" style="border:0"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+7
-7
@@ -28,7 +28,7 @@ const idx = profiles.map((p) => ({
|
|||||||
også på Windows og macOS.
|
også på Windows og macOS.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="drop" class="mt-8 rounded-2xl border border-dashed border-border bg-surface/40 p-8 text-center transition-colors">
|
<div id="drop" class="mt-8 wt-dropzone">
|
||||||
<p class="text-muted">Træk en <code class="rounded bg-surface-2 px-1.5 py-0.5">.xml</code>-fil hertil, eller
|
<p class="text-muted">Træk en <code class="rounded bg-surface-2 px-1.5 py-0.5">.xml</code>-fil hertil, eller
|
||||||
<label class="cursor-pointer text-accent hover:underline">vælg en fil<input id="file" type="file" accept=".xml,text/xml,application/xml" class="hidden" /></label>.
|
<label class="cursor-pointer text-accent hover:underline">vælg en fil<input id="file" type="file" accept=".xml,text/xml,application/xml" class="hidden" /></label>.
|
||||||
</p>
|
</p>
|
||||||
@@ -37,8 +37,8 @@ const idx = profiles.map((p) => ({
|
|||||||
<details class="mt-3">
|
<details class="mt-3">
|
||||||
<summary class="cursor-pointer text-sm text-muted">…eller indsæt XML / en identifikator manuelt</summary>
|
<summary class="cursor-pointer text-sm text-muted">…eller indsæt XML / en identifikator manuelt</summary>
|
||||||
<textarea id="paste" rows="6" placeholder="Indsæt UBL-XML, eller bare en CustomizationID/ProfileID…"
|
<textarea id="paste" rows="6" placeholder="Indsæt UBL-XML, eller bare en CustomizationID/ProfileID…"
|
||||||
class="mt-2 w-full rounded-xl border border-border bg-surface/60 px-4 py-3 font-mono text-xs outline-none focus:border-accent"></textarea>
|
class="mt-2 w-full wt-input wt-input--lg font-mono text-xs"></textarea>
|
||||||
<p class="mt-2"><button id="analyze" type="button" class="rounded-xl bg-accent px-4 py-2 text-sm font-medium text-bg">Afkod</button></p>
|
<p class="mt-2"><button id="analyze" type="button" class="wt-btn wt-btn--primary">Afkod</button></p>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<div id="result" class="mt-6" hidden></div>
|
<div id="result" class="mt-6" hidden></div>
|
||||||
@@ -140,7 +140,7 @@ const idx = profiles.map((p) => ({
|
|||||||
(dec.standard ? ' <span class="text-muted text-base font-normal">· ' + esc(dec.standard) + '</span>' : '') + '</h2>';
|
(dec.standard ? ' <span class="text-muted text-base font-normal">· ' + esc(dec.standard) + '</span>' : '') + '</h2>';
|
||||||
|
|
||||||
result.innerHTML =
|
result.innerHTML =
|
||||||
'<div class="rounded-2xl border border-border bg-surface/60 p-5">' + head +
|
'<div class="wt-card">' + head +
|
||||||
'<dl class="mt-3 space-y-1 text-xs">' +
|
'<dl class="mt-3 space-y-1 text-xs">' +
|
||||||
row('Dokumenttype', '<span class="font-semibold">' + esc(docType) + '</span> (UBL ' + (esc(ublv) || '2.x') + ')') +
|
row('Dokumenttype', '<span class="font-semibold">' + esc(docType) + '</span> (UBL ' + (esc(ublv) || '2.x') + ')') +
|
||||||
row('ID', esc(id)) +
|
row('ID', esc(id)) +
|
||||||
@@ -157,7 +157,7 @@ const idx = profiles.map((p) => ({
|
|||||||
|
|
||||||
function renderId(s) {
|
function renderId(s) {
|
||||||
var dec = decode(s, s);
|
var dec = decode(s, s);
|
||||||
result.innerHTML = '<div class="rounded-2xl border border-border bg-surface/60 p-5">' +
|
result.innerHTML = '<div class="wt-card">' +
|
||||||
(dec.match ? '<div class="flex flex-wrap items-center gap-2">' + badge(dec.match.standard, 'ok') +
|
(dec.match ? '<div class="flex flex-wrap items-center gap-2">' + badge(dec.match.standard, 'ok') +
|
||||||
'</div><h2 class="mt-2 text-xl font-semibold tracking-tight">' + esc(dec.match.navn) + '</h2>'
|
'</div><h2 class="mt-2 text-xl font-semibold tracking-tight">' + esc(dec.match.navn) + '</h2>'
|
||||||
: '<h2 class="text-xl font-semibold tracking-tight">Identifikator</h2>') +
|
: '<h2 class="text-xl font-semibold tracking-tight">Identifikator</h2>') +
|
||||||
@@ -187,9 +187,9 @@ const idx = profiles.map((p) => ({
|
|||||||
function readFile(f) { var r = new FileReader(); r.onload = function () { analyze(String(r.result)); }; r.readAsText(f); }
|
function readFile(f) { var r = new FileReader(); r.onload = function () { analyze(String(r.result)); }; r.readAsText(f); }
|
||||||
fileInput.addEventListener('change', function () { if (fileInput.files[0]) readFile(fileInput.files[0]); });
|
fileInput.addEventListener('change', function () { if (fileInput.files[0]) readFile(fileInput.files[0]); });
|
||||||
['dragenter', 'dragover'].forEach(function (ev) { drop.addEventListener(ev, function (e) {
|
['dragenter', 'dragover'].forEach(function (ev) { drop.addEventListener(ev, function (e) {
|
||||||
e.preventDefault(); drop.classList.add('border-accent'); }); });
|
e.preventDefault(); drop.classList.add('is-over'); }); });
|
||||||
['dragleave', 'drop'].forEach(function (ev) { drop.addEventListener(ev, function (e) {
|
['dragleave', 'drop'].forEach(function (ev) { drop.addEventListener(ev, function (e) {
|
||||||
e.preventDefault(); drop.classList.remove('border-accent'); }); });
|
e.preventDefault(); drop.classList.remove('is-over'); }); });
|
||||||
drop.addEventListener('drop', function (e) { var f = e.dataTransfer && e.dataTransfer.files[0]; if (f) readFile(f); });
|
drop.addEventListener('drop', function (e) { var f = e.dataTransfer && e.dataTransfer.files[0]; if (f) readFile(f); });
|
||||||
document.getElementById('analyze').addEventListener('click', function () { analyze(paste.value); });
|
document.getElementById('analyze').addEventListener('click', function () { analyze(paste.value); });
|
||||||
paste.addEventListener('keydown', function (e) { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') analyze(paste.value); });
|
paste.addEventListener('keydown', function (e) { if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') analyze(paste.value); });
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const sections = [
|
|||||||
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">{s.title}</h2>
|
<h2 class="text-sm font-semibold uppercase tracking-widest text-accent">{s.title}</h2>
|
||||||
<div class="mt-4 space-y-3">
|
<div class="mt-4 space-y-3">
|
||||||
{s.items.map((it) => (
|
{s.items.map((it) => (
|
||||||
<div class="rounded-2xl border border-border bg-surface/60 p-4">
|
<div class="wt-card">
|
||||||
<span class="font-semibold">{it.name}</span>
|
<span class="font-semibold">{it.name}</span>
|
||||||
<p class="mt-1 text-sm text-muted">{it.note}</p>
|
<p class="mt-1 text-sm text-muted">{it.note}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
adapters/tailwind.css feeds the colour tokens into Tailwind's @theme so the
|
adapters/tailwind.css feeds the colour tokens into Tailwind's @theme so the
|
||||||
bg-surface / text-muted / border-border / text-accent utilities are generated
|
bg-surface / text-muted / border-border / text-accent utilities are generated
|
||||||
from the shared palette; weirsoe-theme.css adds the base glow, the sun⇄moon
|
from the shared palette; weirsoe-theme.css adds the base glow, the sun⇄moon
|
||||||
toggle, .prose and the .wt-* components. Replaces the tokens/toggle/prose/glow
|
toggle, .prose and the .wt-* components, in Tailwind's components layer so a
|
||||||
|
utility on the same element (pl-9, font-mono) still wins. Replaces the tokens/toggle/prose/glow
|
||||||
that used to live here by hand. */
|
that used to live here by hand. */
|
||||||
@import "../../vendor/weirsoe-theme/adapters/tailwind.css";
|
@import "../../vendor/weirsoe-theme/adapters/tailwind.css";
|
||||||
@import "../../vendor/weirsoe-theme/weirsoe-theme.css";
|
@import "../../vendor/weirsoe-theme/weirsoe-theme.css" layer(components);
|
||||||
|
|
||||||
/* asger keeps Inter as its UI font (the theme defaults to a system stack). */
|
/* asger keeps Inter as its UI font (the theme defaults to a system stack). */
|
||||||
@theme {
|
@theme {
|
||||||
@@ -19,4 +20,4 @@ html[data-theme="terminal"] {
|
|||||||
}
|
}
|
||||||
/* make the theme's body font follow asger's --font-sans (Inter / mono) */
|
/* make the theme's body font follow asger's --font-sans (Inter / mono) */
|
||||||
:root { --wt-font-sans: var(--font-sans); }
|
:root { --wt-font-sans: var(--font-sans); }
|
||||||
a { color: inherit; }
|
@layer base { a { color: inherit; } }
|
||||||
|
|||||||
Vendored
+1
-1
Submodule vendor/weirsoe-theme updated: b4cad8fef3...495acc9155
Reference in New Issue
Block a user