Merge pull request 'ui-redesign' (#1) from ui-redesign into main
Reviewed-on: #1
This commit is contained in:
commit
fb42c45897
12 changed files with 132 additions and 151 deletions
2
mise.toml
Normal file
2
mise.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[tools]
|
||||||
|
claude = "latest"
|
||||||
|
|
@ -10,7 +10,7 @@ const t = useTranslations(lang);
|
||||||
const year = new Date().getFullYear();
|
const year = new Date().getFullYear();
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer class="border-t border-border/80">
|
<footer class="border-t border-border/80 font-mono">
|
||||||
<div class="mx-auto flex max-w-3xl flex-col gap-2 px-4 py-8 text-sm text-text-muted sm:flex-row sm:items-center sm:justify-between sm:px-6">
|
<div class="mx-auto flex max-w-3xl flex-col gap-2 px-4 py-8 text-sm text-text-muted sm:flex-row sm:items-center sm:justify-between sm:px-6">
|
||||||
<p>
|
<p>
|
||||||
© {year} <span class="font-mono text-text">gabeefranco</span> · {t('footer.rights')}
|
© {year} <span class="font-mono text-text">gabeefranco</span> · {t('footer.rights')}
|
||||||
|
|
|
||||||
|
|
@ -28,72 +28,79 @@ function isActive(href: string): boolean {
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
<header class="sticky top-0 z-40 border-b border-border/80 bg-bg/85 backdrop-blur">
|
<header class="sticky top-0 z-40 border-b border-border/80 bg-bg/85 backdrop-blur">
|
||||||
<div class="mx-auto flex max-w-3xl items-center justify-between gap-4 px-4 py-3 sm:px-6">
|
<div class="flex flex-col justify-center gap-4 px-4 py-3 sm:px-6">
|
||||||
<a href={homeHref} class="flex shrink-0 items-center gap-2.5" aria-label={t('site.name')}>
|
<div class="flex flex-row justify-between items-end">
|
||||||
<img src="/favicon.svg" alt="" width="32" height="32" class="size-8" />
|
<a href={homeHref} class="flex hover:underline shrink-0 items-center gap-2.5" aria-label={t('site.name')}>
|
||||||
|
<img src="/logo.png" class="h-4"/>
|
||||||
<span class="font-mono text-[15px] font-semibold tracking-tight text-text">{t('site.name')}</span>
|
<span class="font-mono text-[15px] font-semibold tracking-tight text-text">{t('site.name')}</span>
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<nav class="hidden items-center gap-1 sm:flex" aria-label={t('nav.menu')}>
|
|
||||||
{navLinks.map((link) => (
|
|
||||||
<a
|
|
||||||
href={link.href}
|
|
||||||
aria-current={isActive(link.href) ? 'page' : undefined}
|
|
||||||
class:list={[
|
|
||||||
'rounded-full px-3 py-1.5 text-sm font-medium transition-colors',
|
|
||||||
isActive(link.href)
|
|
||||||
? 'bg-primary/10 text-primary'
|
|
||||||
: 'text-text-muted hover:bg-surface-alt hover:text-text',
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{link.label}
|
|
||||||
</a>
|
</a>
|
||||||
))}
|
<div class="ml-10 flex sm:hidden justify-end gap-3">
|
||||||
</nav>
|
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={langSwitchHref}
|
href={langSwitchHref}
|
||||||
hreflang={otherLang}
|
hreflang={otherLang}
|
||||||
title={t('lang.switch')}
|
title={t('lang.switch')}
|
||||||
aria-label={`${t('lang.switch')}: ${LANG_LABELS[otherLang]}`}
|
aria-label={`${t('lang.switch')}: ${LANG_LABELS[otherLang]}`}
|
||||||
class="grid size-9 shrink-0 place-items-center rounded-full border border-border text-xs font-bold uppercase text-text-muted transition-colors hover:border-primary hover:text-primary"
|
class="text-accent max-w-fit font-mono text-xs sm:text-sm underline hover:cursor-pointer hover:text-accent-deep"
|
||||||
>
|
>
|
||||||
{otherLang}
|
{`${t('lang.switch')}: ${LANG_LABELS[otherLang]}`}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<ThemeToggle lang={lang} />
|
<ThemeToggle lang={lang} />
|
||||||
|
</div>
|
||||||
|
<div class="hidden sm:flex items-center gap-2">
|
||||||
|
|
||||||
<details class="relative sm:hidden">
|
<nav class="flex items-center gap-1 justify-right" aria-label={t('nav.menu')}>
|
||||||
<summary
|
|
||||||
class="grid size-9 cursor-pointer list-none place-items-center rounded-full border border-border text-text-muted transition-colors hover:border-primary hover:text-primary"
|
|
||||||
aria-label={t('nav.menu')}
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" class="size-[18px]">
|
|
||||||
<path d="M4 6h16M4 12h16M4 18h16"></path>
|
|
||||||
</svg>
|
|
||||||
</summary>
|
|
||||||
<nav
|
|
||||||
class="absolute right-0 top-11 flex w-40 flex-col gap-1 rounded-xl border border-border bg-surface p-2 shadow-lg"
|
|
||||||
aria-label={t('nav.menu')}
|
|
||||||
>
|
|
||||||
{navLinks.map((link) => (
|
{navLinks.map((link) => (
|
||||||
<a
|
<a
|
||||||
href={link.href}
|
href={link.href}
|
||||||
aria-current={isActive(link.href) ? 'page' : undefined}
|
aria-current={isActive(link.href) ? 'page' : undefined}
|
||||||
class:list={[
|
class:list={[
|
||||||
'rounded-lg px-3 py-2 text-sm font-medium transition-colors',
|
'px-2 py-1 text-sm font-medium font-mono underline',
|
||||||
isActive(link.href)
|
isActive(link.href)
|
||||||
? 'bg-primary/10 text-primary'
|
? 'text-primary hover:text-primary-hover'
|
||||||
: 'text-text-muted hover:bg-surface-alt hover:text-text',
|
: 'text-text-muted hover:text-text',
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{link.label}
|
{link.label}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
</details>
|
<a
|
||||||
|
href={langSwitchHref}
|
||||||
|
hreflang={otherLang}
|
||||||
|
title={t('lang.switch')}
|
||||||
|
aria-label={`${t('lang.switch')}: ${LANG_LABELS[otherLang]}`}
|
||||||
|
class="text-accent max-w-fit py-1 font-mono text-xs sm:text-sm underline hover:cursor-pointer hover:text-accent-deep "
|
||||||
|
>
|
||||||
|
{`${t('lang.switch')}: ${LANG_LABELS[otherLang]}`}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<ThemeToggle lang={lang} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-end sm:hidden items-center gap-2">
|
||||||
|
<nav class="flex items-center gap-1 justify-right" aria-label={t('nav.menu')}>
|
||||||
|
{navLinks.map((link) => (
|
||||||
|
<a
|
||||||
|
href={link.href}
|
||||||
|
aria-current={isActive(link.href) ? 'page' : undefined}
|
||||||
|
class:list={[
|
||||||
|
'px-2 py-1 text-sm font-medium font-mono underline',
|
||||||
|
isActive(link.href)
|
||||||
|
? 'text-primary hover:text-primary-hover'
|
||||||
|
: 'text-text-muted hover:text-text',
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
||||||
|
|
@ -15,47 +15,54 @@ const postsHref = getLocalizedPath('/posts', lang);
|
||||||
const aboutHref = getLocalizedPath('/about', lang);
|
const aboutHref = getLocalizedPath('/about', lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<section class="mx-auto max-w-3xl px-4 pb-4 pt-14 sm:px-6 sm:pt-20">
|
<section class="mx-10 my-10 flex flex-col gap-5 font-mono">
|
||||||
<div class="flex flex-col items-start gap-8 sm:flex-row sm:items-center">
|
<div class="flex flex-col gap-2">
|
||||||
<img
|
<h1 class="text-text text-2xl">{t('hero.title')}</h1>
|
||||||
src="/logo.png"
|
<h2 class="text-text text-lg">{t('hero.subtitle')}</h2>
|
||||||
alt=""
|
|
||||||
width="867"
|
|
||||||
height="458"
|
|
||||||
class="w-40 shrink-0 drop-shadow-sm sm:w-52"
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<p class="text-sm font-semibold uppercase tracking-wide text-primary">{t('hero.kicker')}</p>
|
|
||||||
<h1 class="mt-2 text-3xl font-bold tracking-tight text-text sm:text-4xl">{t('hero.title')}</h1>
|
|
||||||
<p class="mt-4 max-w-xl text-lg leading-relaxed text-text-muted">{t('hero.subtitle')}</p>
|
|
||||||
<div class="mt-6 flex flex-wrap gap-3">
|
|
||||||
<a
|
|
||||||
href={postsHref}
|
|
||||||
class="rounded-full bg-primary px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-primary-hover"
|
|
||||||
>
|
|
||||||
{t('hero.cta.posts')}
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href={aboutHref}
|
|
||||||
class="rounded-full border border-border px-5 py-2.5 text-sm font-semibold text-text transition-colors hover:border-primary hover:text-primary"
|
|
||||||
>
|
|
||||||
{t('hero.cta.about')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="mx-auto max-w-3xl px-4 py-12 sm:px-6">
|
<!-- <section class="mx-auto max-w-3xl px-4 pb-4 pt-14 sm:px-6 sm:pt-20 font-mono"> -->
|
||||||
|
<!-- <div class="flex flex-col items-start gap-8 sm:flex-row sm:items-center"> -->
|
||||||
|
<!-- <img -->
|
||||||
|
<!-- src="/logo.png" -->
|
||||||
|
<!-- alt="" -->
|
||||||
|
<!-- width="867" -->
|
||||||
|
<!-- height="458" -->
|
||||||
|
<!-- class="w-40 shrink-0 drop-shadow-sm sm:w-52" -->
|
||||||
|
<!-- /> -->
|
||||||
|
<!-- <div> -->
|
||||||
|
<!-- <p class="text-sm font-semibold uppercase tracking-wide text-primary">{t('hero.kicker')}</p> -->
|
||||||
|
<!-- <h1 class="mt-2 text-3xl font-bold tracking-tight text-text sm:text-4xl">{t('hero.title')}</h1> -->
|
||||||
|
<!-- <p class="mt-4 max-w-xl text-lg leading-relaxed text-text-muted">{t('hero.subtitle')}</p> -->
|
||||||
|
<!-- <div class="mt-6 flex flex-wrap gap-5"> -->
|
||||||
|
<!-- <a -->
|
||||||
|
<!-- href={postsHref} -->
|
||||||
|
<!-- class="text-primary hover:underline font-bold px-2 py-1 bg-primary/10" -->
|
||||||
|
<!-- > -->
|
||||||
|
<!-- {t('hero.cta.posts')} -->
|
||||||
|
<!-- </a> -->
|
||||||
|
<!-- <a -->
|
||||||
|
<!-- href={aboutHref} -->
|
||||||
|
<!-- class="text-text hover:underline font-bold px-2 py-1 bg-text/5" -->
|
||||||
|
<!-- > -->
|
||||||
|
<!-- {t('hero.cta.about')} -->
|
||||||
|
<!-- </a> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
<!-- </section> -->
|
||||||
|
|
||||||
|
<section class="mx-10 font-mono">
|
||||||
<div class="flex items-baseline justify-between gap-4">
|
<div class="flex items-baseline justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-xl font-semibold text-text">{t('home.recent')}</h2>
|
<h2 class="text-xl font-semibold text-text">{t('home.recent')}</h2>
|
||||||
<p class="mt-1 text-sm text-text-muted">{t('home.recent.subtitle')}</p>
|
<p class="mt-1 text-sm text-text-muted mb-2">{t('home.recent.subtitle')}</p>
|
||||||
</div>
|
|
||||||
<a href={postsHref} class="shrink-0 text-sm font-medium text-primary hover:underline">
|
<a href={postsHref} class="shrink-0 text-sm font-medium text-primary hover:underline">
|
||||||
{t('home.viewAll')} →
|
{t('home.viewAll')} →
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{recentPosts.length > 0 ? (
|
{recentPosts.length > 0 ? (
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ const href = getLocalizedPath(`/posts/${slugOf(post)}`, lang);
|
||||||
const tagsHref = (tag: string) => getLocalizedPath(`/tags/${tag}`, lang);
|
const tagsHref = (tag: string) => getLocalizedPath(`/tags/${tag}`, lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<article class="group border-b border-border py-6 first:pt-0 last:border-b-0">
|
<article class="group border-b border-border py-6 first:pt-0 last:border-b-0 font-mono">
|
||||||
<a href={href} class="block">
|
<a href={href} class="block">
|
||||||
<time datetime={post.data.pubDate.toISOString()} class="text-xs font-medium uppercase tracking-wide text-text-muted">
|
<time datetime={post.data.pubDate.toISOString()} class="text-xs font-medium uppercase tracking-wide text-text-muted">
|
||||||
{formatDate(post.data.pubDate, lang)}
|
{formatDate(post.data.pubDate, lang)}
|
||||||
</time>
|
</time>
|
||||||
<h3 class="mt-1.5 text-xl font-semibold text-text transition-colors group-hover:text-primary">
|
<h3 class="mt-1.5 text-xl font-semibold text-text group-hover:text-primary group-hover:underline">
|
||||||
{post.data.title}
|
{post.data.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="mt-1.5 text-[15px] leading-relaxed text-text-muted">{post.data.description}</p>
|
<p class="mt-1.5 text-[15px] leading-relaxed text-text-muted">{post.data.description}</p>
|
||||||
|
|
@ -28,7 +28,7 @@ const tagsHref = (tag: string) => getLocalizedPath(`/tags/${tag}`, lang);
|
||||||
{post.data.tags.map((tag) => (
|
{post.data.tags.map((tag) => (
|
||||||
<a
|
<a
|
||||||
href={tagsHref(tag)}
|
href={tagsHref(tag)}
|
||||||
class="rounded-full bg-surface-alt px-2.5 py-1 text-xs font-medium text-text-muted transition-colors hover:bg-accent/15 hover:text-accent"
|
class="text-text-muted px-1 py-0.5 text-sm hover:text-accent underline"
|
||||||
>
|
>
|
||||||
#{tag}
|
#{tag}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,19 @@ const posts = tag ? allPosts.filter((p) => p.data.tags.includes(tag)) : allPosts
|
||||||
const postsHref = getLocalizedPath('/posts', lang);
|
const postsHref = getLocalizedPath('/posts', lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<section class="mx-auto max-w-3xl px-4 py-12 sm:px-6">
|
<section class="mx-10 mt-10">
|
||||||
{tag ? (
|
{tag ? (
|
||||||
<>
|
<>
|
||||||
<p class="text-sm font-medium text-text-muted">{t('posts.filteredBy')}</p>
|
<p class="text-sm font-mono font-medium text-text-muted">{t('posts.filteredBy')}</p>
|
||||||
<h1 class="mt-1 text-3xl font-bold tracking-tight text-text">#{tag}</h1>
|
<h1 class="mt-1 font-mono text-3xl font-bold tracking-tight text-text">#{tag}</h1>
|
||||||
<a href={postsHref} class="mt-2 inline-block text-sm font-medium text-primary hover:underline">
|
<a href={postsHref} class="font-mono mt-2 inline-block text-sm font-medium text-primary hover:underline">
|
||||||
{t('posts.clearFilter')}
|
{t('posts.clearFilter')}
|
||||||
</a>
|
</a>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<h1 class="text-3xl font-bold tracking-tight text-text">{t('posts.title')}</h1>
|
<h1 class="font-mono text-3xl font-bold tracking-tight text-text">{t('posts.title')}</h1>
|
||||||
<p class="mt-2 text-text-muted">{t('posts.subtitle')}</p>
|
<p class="font-mono mt-2 text-text-muted">{t('posts.subtitle')}</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,61 +11,26 @@ const t = useTranslations(lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<button
|
<button
|
||||||
id="theme-toggle"
|
|
||||||
type="button"
|
type="button"
|
||||||
|
class="theme-toggle text-accent sm:ml-2 font-mono text-xs sm:text-sm underline hover:cursor-pointer hover:text-accent-deep"
|
||||||
aria-label={t('theme.switch')}
|
aria-label={t('theme.switch')}
|
||||||
title={t('theme.switch')}
|
title={t('theme.switch')}
|
||||||
class="grid size-9 shrink-0 place-items-center rounded-full border border-border text-text-muted transition-colors hover:border-primary hover:text-primary"
|
|
||||||
>
|
>
|
||||||
<svg
|
{t('theme.switch')}
|
||||||
id="theme-toggle-sun"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="hidden size-[18px]"
|
|
||||||
>
|
|
||||||
<circle cx="12" cy="12" r="4"></circle>
|
|
||||||
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
<svg
|
|
||||||
id="theme-toggle-moon"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
class="hidden size-[18px]"
|
|
||||||
>
|
|
||||||
<path d="M20 14.5A8.5 8.5 0 1 1 9.5 4a6.5 6.5 0 0 0 10.5 10.5Z"></path>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<script is:inline>
|
<script>
|
||||||
(function () {
|
function init() {
|
||||||
const btn = document.getElementById('theme-toggle');
|
const buttons = document.querySelectorAll('.theme-toggle');
|
||||||
const sun = document.getElementById('theme-toggle-sun');
|
buttons.forEach((btn) => {
|
||||||
const moon = document.getElementById('theme-toggle-moon');
|
|
||||||
if (!btn || !sun || !moon) return;
|
|
||||||
|
|
||||||
function sync() {
|
|
||||||
const isDark = document.documentElement.classList.contains('dark');
|
|
||||||
sun.classList.toggle('hidden', !isDark);
|
|
||||||
moon.classList.toggle('hidden', isDark);
|
|
||||||
}
|
|
||||||
|
|
||||||
btn.addEventListener('click', function () {
|
btn.addEventListener('click', function () {
|
||||||
const isDark = document.documentElement.classList.toggle('dark');
|
const isDark = document.documentElement.classList.toggle('dark');
|
||||||
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
localStorage.setItem('theme', isDark ? 'dark' : 'light');
|
||||||
sync();
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
sync();
|
init();
|
||||||
})();
|
|
||||||
|
document.addEventListener('astro:after-swap', init);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ const postsHref = getLocalizedPath('/posts', lang);
|
||||||
const tagsHref = (tag: string) => getLocalizedPath(`/tags/${tag}`, lang);
|
const tagsHref = (tag: string) => getLocalizedPath(`/tags/${tag}`, lang);
|
||||||
---
|
---
|
||||||
|
|
||||||
<article class="mx-auto max-w-3xl px-4 py-12 sm:px-6">
|
<article class="mx-10 mt-10 font-mono">
|
||||||
<a href={postsHref} class="inline-flex items-center gap-1.5 text-sm font-medium text-text-muted transition-colors hover:text-primary">
|
<a href={postsHref} class="underline inline-flex items-center gap-1.5 text-sm font-medium text-text-muted hover:text-primary">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-4">
|
||||||
<path d="M15 18l-6-6 6-6"></path>
|
<path d="M15 18l-6-6 6-6"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
@ -42,7 +42,7 @@ const tagsHref = (tag: string) => getLocalizedPath(`/tags/${tag}`, lang);
|
||||||
{post.data.tags.map((tag) => (
|
{post.data.tags.map((tag) => (
|
||||||
<a
|
<a
|
||||||
href={tagsHref(tag)}
|
href={tagsHref(tag)}
|
||||||
class="rounded-full bg-surface-alt px-2.5 py-1 text-xs font-medium text-text-muted transition-colors hover:bg-accent/15 hover:text-accent"
|
class=" text-xs font-medium text-text-muted underline hover:text-accent"
|
||||||
>
|
>
|
||||||
#{tag}
|
#{tag}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export const ui = {
|
||||||
'hero.kicker': "Gabriel Franco's notes",
|
'hero.kicker': "Gabriel Franco's notes",
|
||||||
'hero.title': 'Building things, and figuring out how they work.',
|
'hero.title': 'Building things, and figuring out how they work.',
|
||||||
'hero.subtitle':
|
'hero.subtitle':
|
||||||
"Notes on computer science, systems, and the open source projects that shaped how I think about software. I'm gabeefranco — welcome.",
|
"Notes on computer science, systems, and the open source projects that shaped how I think about software. I'm Gabriel Franco — welcome.",
|
||||||
'hero.cta.posts': 'Read the posts',
|
'hero.cta.posts': 'Read the posts',
|
||||||
'hero.cta.about': 'About me',
|
'hero.cta.about': 'About me',
|
||||||
'home.recent': 'Recent posts',
|
'home.recent': 'Recent posts',
|
||||||
|
|
@ -54,7 +54,7 @@ export const ui = {
|
||||||
'hero.kicker': 'Anotações do Gabriel Franco',
|
'hero.kicker': 'Anotações do Gabriel Franco',
|
||||||
'hero.title': 'Construindo coisas e entendendo como elas funcionam.',
|
'hero.title': 'Construindo coisas e entendendo como elas funcionam.',
|
||||||
'hero.subtitle':
|
'hero.subtitle':
|
||||||
'Notas sobre ciência da computação, sistemas e os projetos open source que moldaram a forma como penso sobre software. Eu sou o gabeefranco — seja bem-vindo.',
|
'Notas sobre ciência da computação, sistemas e os projetos open source que moldaram a forma como penso sobre software. Eu sou o Gabriel Franco — seja bem-vindo.',
|
||||||
'hero.cta.posts': 'Ler os posts',
|
'hero.cta.posts': 'Ler os posts',
|
||||||
'hero.cta.about': 'Sobre mim',
|
'hero.cta.about': 'Sobre mim',
|
||||||
'home.recent': 'Posts recentes',
|
'home.recent': 'Posts recentes',
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const langs: Lang[] = ['en', 'pt'];
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={`${ui.en['404.title']} — gabeefranco`} description={ui.en['404.body']} lang="en">
|
<BaseLayout title={`${ui.en['404.title']} — gabeefranco`} description={ui.en['404.body']} lang="en">
|
||||||
<section class="mx-auto flex max-w-3xl flex-col items-start px-4 py-24 sm:px-6">
|
<section class="mx-10 flex flex-col items-start px-4 py-24 sm:px-6 font-mono">
|
||||||
<p class="font-mono text-sm text-primary">404</p>
|
<p class="font-mono text-sm text-primary">404</p>
|
||||||
{langs.map((lang) => (
|
{langs.map((lang) => (
|
||||||
<div data-notfound-lang={lang} class={lang === 'en' ? '' : 'hidden'}>
|
<div data-notfound-lang={lang} class={lang === 'en' ? '' : 'hidden'}>
|
||||||
|
|
@ -18,7 +18,7 @@ const langs: Lang[] = ['en', 'pt'];
|
||||||
<p class="mt-3 text-text-muted">{ui[lang]['404.body']}</p>
|
<p class="mt-3 text-text-muted">{ui[lang]['404.body']}</p>
|
||||||
<a
|
<a
|
||||||
href={getLocalizedPath('/', lang)}
|
href={getLocalizedPath('/', lang)}
|
||||||
class="mt-6 inline-block rounded-full bg-primary px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-primary-hover"
|
class="mt-4 inline-block underline text-primary hover:text-primary-hover font-bold"
|
||||||
>
|
>
|
||||||
{ui[lang]['404.cta']}
|
{ui[lang]['404.cta']}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const description =
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={`${t('about.title')} — ${t('site.name')}`} description={description} lang="en">
|
<BaseLayout title={`${t('about.title')} — ${t('site.name')}`} description={description} lang="en">
|
||||||
<section class="mx-auto max-w-3xl px-4 py-14 sm:px-6">
|
<section class="mx-10 mt-10 font-mono">
|
||||||
<h1 class="text-3xl font-bold tracking-tight text-text sm:text-4xl">{t('about.title')}</h1>
|
<h1 class="text-3xl font-bold tracking-tight text-text sm:text-4xl">{t('about.title')}</h1>
|
||||||
|
|
||||||
<div class="prose prose-neutral mt-6 max-w-none prose-headings:font-semibold prose-a:text-primary prose-a:no-underline hover:prose-a:underline dark:prose-invert">
|
<div class="prose prose-neutral mt-6 max-w-none prose-headings:font-semibold prose-a:text-primary prose-a:no-underline hover:prose-a:underline dark:prose-invert">
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const description =
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={`${t('about.title')} — ${t('site.name')}`} description={description} lang="pt">
|
<BaseLayout title={`${t('about.title')} — ${t('site.name')}`} description={description} lang="pt">
|
||||||
<section class="mx-auto max-w-3xl px-4 py-14 sm:px-6">
|
<section class="mx-10 mt-10 font-mono">
|
||||||
<h1 class="text-3xl font-bold tracking-tight text-text sm:text-4xl">{t('about.title')}</h1>
|
<h1 class="text-3xl font-bold tracking-tight text-text sm:text-4xl">{t('about.title')}</h1>
|
||||||
|
|
||||||
<div class="prose prose-neutral mt-6 max-w-none prose-headings:font-semibold prose-a:text-primary prose-a:no-underline hover:prose-a:underline dark:prose-invert">
|
<div class="prose prose-neutral mt-6 max-w-none prose-headings:font-semibold prose-a:text-primary prose-a:no-underline hover:prose-a:underline dark:prose-invert">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue