Merge branch 'main' of git.sr.ht:~ayoayco/ayco.io-astro into main
This commit is contained in:
commit
620b021e67
18 changed files with 3817 additions and 5724 deletions
9107
package-lock.json
generated
9107
package-lock.json
generated
File diff suppressed because it is too large
Load diff
15
package.json
15
package.json
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@example/basics",
|
||||
"name": "@ayco/personal-website",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
|
@ -8,13 +8,14 @@
|
|||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
"astro": "astro",
|
||||
"deploy": "astro build && scp -r dist/. ayo@ayco.io:~/ayco.io-astro/dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astro-reactive/form": "^0.8.1",
|
||||
"@astro-reactive/validator": "^0.3.4",
|
||||
"astro": "^2.5.5",
|
||||
"astro-github-stats": "^0.5.0",
|
||||
"astro-icon": "^0.8.0"
|
||||
"@astro-reactive/form": "^0.10.0",
|
||||
"@astro-reactive/validator": "^0.5.0",
|
||||
"astro": "^4.0.3",
|
||||
"astro-github-stats": "^0.7.0",
|
||||
"astro-iconify": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
|
BIN
public/ayo-sm.png
Normal file
BIN
public/ayo-sm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -16,8 +16,8 @@ const { href, title, rel, body, newTab = false } = Astro.props;
|
|||
{title}
|
||||
{
|
||||
newTab
|
||||
? (<span>↗</span>)
|
||||
: (<span>→ </span>)
|
||||
? (<span> ↗</span>)
|
||||
: (<span> →</span>)
|
||||
}
|
||||
</h2>
|
||||
<p>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
---
|
||||
const year = new Date().getFullYear();
|
||||
---
|
||||
<footer>
|
||||
<ul role="list" style="list-style:none">
|
||||
<li>2022 © <strong>Ayo Ayco</strong>. All Rights Reserved</li>
|
||||
<li>This website does not track users.</li>
|
||||
<li><a href="https://git.sr.ht/~ayoayco/ayco.io-astro">See the source code</a></li>
|
||||
<ul style="list-style:none">
|
||||
<li>© 2022-{year} <strong>Ayo Ayco</strong>. All Rights Reserved</li>
|
||||
<li>This website <a href="https://ayos.blog/stopped-tracking-on-my-sites">does not track users</a></li>
|
||||
<li>See the <a href="https://ayco.io/sh/ayco.io-astro/tree">source code</a></li>
|
||||
</ul>
|
||||
</footer>
|
||||
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
---
|
||||
import Icon from "astro-icon";
|
||||
export type Link = {
|
||||
url: string;
|
||||
icon: string;
|
||||
text?: string;
|
||||
};
|
||||
import Icon from "astro-iconify";
|
||||
import type { Link } from "../constants/links";
|
||||
|
||||
export interface Props {
|
||||
links: Array<Link>;
|
||||
links: Link[];
|
||||
}
|
||||
|
||||
let { links } = Astro.props;
|
||||
|
||||
if (Astro.url.pathname !== "/") {
|
||||
links = [{
|
||||
links = [
|
||||
{
|
||||
url: "/",
|
||||
icon: "home",
|
||||
}].concat(links);
|
||||
},
|
||||
].concat(links);
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
<nav>
|
||||
<nav>
|
||||
<div id="wrapper">
|
||||
{
|
||||
links
|
||||
.filter((link) => link.url !== "")
|
||||
.map((link) => (
|
||||
<a href={link.url}>
|
||||
<Icon pack="mdi" name={link.icon} /> {link.text ?? link.icon}
|
||||
<Icon pack={link.set ?? "mdi"} name={link.icon} />{" "}
|
||||
{link.text ?? link.icon}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</nav>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
nav {
|
||||
|
@ -63,11 +63,11 @@ if (Astro.url.pathname !== "/") {
|
|||
}
|
||||
|
||||
@media only screen and (max-device-width: 360px) {
|
||||
#wrapper { text-align: center; }
|
||||
#wrapper {
|
||||
text-align: center;
|
||||
}
|
||||
nav a {
|
||||
padding: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
|
30
src/constants/links.ts
Normal file
30
src/constants/links.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
export type Link = {
|
||||
url: string;
|
||||
icon: string;
|
||||
set?: string;
|
||||
text?: string;
|
||||
};
|
||||
|
||||
|
||||
export const links: Link[] = [
|
||||
{
|
||||
url: "https://ayos.blog",
|
||||
icon: "blog",
|
||||
},
|
||||
{
|
||||
url: "https://ayco.io/@ayo",
|
||||
icon: "mastodon",
|
||||
text: "social"
|
||||
},
|
||||
{
|
||||
url: "https://ayco.io/gh/",
|
||||
icon: "github",
|
||||
},
|
||||
{
|
||||
url: "https://www.npmjs.com/~aayco",
|
||||
icon: "npm",
|
||||
set: "gg"
|
||||
}
|
||||
];
|
||||
|
||||
export default links;
|
55
src/constants/stuff.ts
Normal file
55
src/constants/stuff.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
export const stuff: {
|
||||
icon: string;
|
||||
text: string;
|
||||
link?: {url: string, text: string};
|
||||
}[] = [
|
||||
// {
|
||||
// icon: '🧐',
|
||||
// text: 'Software Extraordinaire'
|
||||
// },
|
||||
// {
|
||||
// icon: '🕵🏻♂️',
|
||||
// text: 'Frontend Detective'
|
||||
// },
|
||||
{
|
||||
icon: '😱',
|
||||
text: 'Building',
|
||||
link: {
|
||||
url: 'https://mcfly.js.org',
|
||||
text: 'McFly'
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: '🧸',
|
||||
text: 'Creator of',
|
||||
link: {
|
||||
url: 'https://ayco.io/gh/cozy#readme',
|
||||
text: 'Cozy'
|
||||
}
|
||||
},
|
||||
{
|
||||
icon: '🧱',
|
||||
text: 'Creator of',
|
||||
link: {
|
||||
url: 'https://webcomponent.io',
|
||||
text: 'WebComponent.io'
|
||||
}
|
||||
},
|
||||
// {
|
||||
// icon: '🧱',
|
||||
// text: '...and some',
|
||||
// link: {
|
||||
// url: '/stuff',
|
||||
// text: 'small stuff'
|
||||
// }
|
||||
// },
|
||||
{
|
||||
icon: '🦌',
|
||||
text: 'Contributor to',
|
||||
link: {
|
||||
url: 'https://elk.zone/@ayo@ayco.io',
|
||||
text: 'Elk.zone'
|
||||
}
|
||||
}
|
||||
]
|
|
@ -2,33 +2,14 @@
|
|||
import "./reset.css";
|
||||
import Head from "../components/Head.astro";
|
||||
import Nav from "../components/Nav.astro";
|
||||
import type { Link } from "../components/Nav.astro";
|
||||
import links from "../constants/links";
|
||||
export interface Props {
|
||||
title?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const { title, description } = Astro.props;
|
||||
const links: Link[] = [
|
||||
{
|
||||
url: "https://ayos.blog",
|
||||
icon: "blog",
|
||||
},
|
||||
{
|
||||
url: "https://ayco.io/@ayo",
|
||||
icon: "mastodon",
|
||||
text: "social"
|
||||
},
|
||||
{
|
||||
url: "https://ayco.io/gh",
|
||||
icon: "github",
|
||||
},
|
||||
{
|
||||
url: "https://codepen.io/ayoayco-the-styleful",
|
||||
icon: "codepen",
|
||||
text: "pens"
|
||||
}
|
||||
];
|
||||
|
||||
---
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
@ -101,9 +82,8 @@ const links: Link[] = [
|
|||
}
|
||||
|
||||
a {
|
||||
font-weight: 900;
|
||||
font-weight: bold;
|
||||
color: var(--color-link);
|
||||
border-radius: 0.4rem;
|
||||
}
|
||||
|
||||
p,
|
||||
|
|
|
@ -31,6 +31,7 @@ body {
|
|||
*/
|
||||
body {
|
||||
line-height: 1.5;
|
||||
letter-spacing: 0.25px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -2,15 +2,7 @@
|
|||
import Layout from "../layouts/Layout.astro";
|
||||
import Card from "../components/Card.astro";
|
||||
import Footer from "../components/Footer.astro";
|
||||
|
||||
const response = await fetch('https://social.ayco.io/api/v1/accounts/109547735999980313')
|
||||
let {
|
||||
avatar,
|
||||
note
|
||||
} = await response.json();
|
||||
|
||||
note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<span class="">ayco.io/sh/', '<span class="">')
|
||||
|
||||
import { stuff } from '../constants/stuff';
|
||||
---
|
||||
|
||||
<Layout>
|
||||
|
@ -19,24 +11,37 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
<img
|
||||
class="highlighted-section__content__profile-picture"
|
||||
alt="Ayo Ayco's picture"
|
||||
src={avatar}
|
||||
width="150"
|
||||
src='/ayo-sm.png'
|
||||
width="140"
|
||||
height="140"
|
||||
/>
|
||||
<div class="highlighted-section__content__text">
|
||||
<h1 title="Ayo Ayco | Software Engineer + Web Developer">
|
||||
<span class="heavy-text">Ayo</span>Ayco
|
||||
</h1>
|
||||
<div class="highlighted__note" set:html={note} />
|
||||
<ul>
|
||||
{
|
||||
stuff.map(({ icon, text, link }) => (
|
||||
<li style="display:flex;gap:0.25em">
|
||||
<span class="icon">{icon}</span>
|
||||
<span class="text">{text}</span>
|
||||
{link && <a href={link.url}>{link.text}</a>}
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
<a href="/now" class="now-wrapper">
|
||||
<span class="now-label">Now</span>
|
||||
<span class="status">Building a Cozy Web without borders...</span>
|
||||
<span class="status"
|
||||
>Certified Software Architecture Professional</span
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<main>
|
||||
<section class="cards-section">
|
||||
<ul role="list" class="cards-section__grid">
|
||||
<ul class="cards-section__grid">
|
||||
<Card
|
||||
href="/showcase"
|
||||
title="Fun Side Projects"
|
||||
|
@ -44,7 +49,7 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
/>
|
||||
<Card
|
||||
newTab={true}
|
||||
href="/cv"
|
||||
href="https://ayco.io/cv"
|
||||
title="CV / Resume"
|
||||
body="Download and peruse my skills and experience"
|
||||
/>
|
||||
|
@ -84,6 +89,7 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
margin-right: 0.25em;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -110,11 +116,13 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
|
||||
.highlighted-section__content__profile-picture {
|
||||
float: right;
|
||||
width: 20%;
|
||||
margin: 1em 1em 0 0;
|
||||
border: 1px solid var(--color-brand-blue-1);
|
||||
border: 5px solid var(--color-brand-blue-1);
|
||||
background-color: var(--color-brand-blue-1);
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
.highlighted-section__content ul a {
|
||||
|
@ -127,6 +135,10 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
.highlighted-section__content ul li {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.cards-section {
|
||||
margin: auto;
|
||||
max-width: var(--content-width);
|
||||
|
@ -142,6 +154,7 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
@media only screen and (max-device-width: 360px) {
|
||||
.now-wrapper {
|
||||
border: 0px;
|
||||
border-radius: 0;
|
||||
font-size: var(--font-size-sm);
|
||||
width: 100%;
|
||||
|
||||
|
@ -152,25 +165,24 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.now-label {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
display:none
|
||||
}
|
||||
|
||||
.status::before {
|
||||
content: 'Now: '
|
||||
}
|
||||
|
||||
.status {
|
||||
text-decoration: underline;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.now-label::before {
|
||||
content: "* ";
|
||||
}
|
||||
|
||||
.now-label::after {
|
||||
content: ":";
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.highlighted-section__content__profile-picture {
|
||||
float: none;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,6 +194,7 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
float: none;
|
||||
margin: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.highlighted-section__content ul li {
|
||||
font-size: var(--font-size-sm);
|
||||
|
@ -197,13 +210,3 @@ note = note.replace('<span class="">ayco.io/gh/', '<span class="">').replace('<s
|
|||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style is:inline>
|
||||
.invisible {
|
||||
display: none;
|
||||
}
|
||||
.highlighted__note a {
|
||||
color: white;
|
||||
font-weight: normal;
|
||||
}
|
||||
</style>
|
|
@ -10,18 +10,13 @@ const posts = await Astro.glob("./now/and-then/posts/*.astro");
|
|||
<main>
|
||||
<h1><span class="text-gradient">Now</span></h1>
|
||||
<em>What am I currently up to?</em>
|
||||
<p>
|
||||
Recently started a new project that aims to be a modern-day reading assistant, called <a href="https://ayco.io/gh/cozy">Cozy 🧸</a>.
|
||||
</p>
|
||||
<p>
|
||||
The full motivation as of the moment, I've written on <a href="https://ayos.blog/building-a-cozy-web/">my blog</a>.
|
||||
</p>
|
||||
<p>
|
||||
Also started exploring ways to interact on the web without being confined on a centralized solution that big tech companies have lured us into.
|
||||
</p>
|
||||
<p>
|
||||
I mean protocols that allow websites and people to exchange messages with each other without borders, like <a href="https://www.w3.org/TR/webmention/">webmention</a>, <a href="https://www.w3.org/TR/activitypub/">activitypub</a>, and the likes.
|
||||
</p>
|
||||
|
||||
<p>🎉 Thrilled to share I am now a Certified Professional for Software Architecture (CPSA-F®) after having completed and passed the <a href="https://www.isaqb.org/" target="_blank">iSAQB® – International Software Architecture Qualification Board</a>'s intensive training and examination.</p>
|
||||
|
||||
<p>This means I have the necessary basis for facilitating / participating in architectural design activities for software development.</p>
|
||||
|
||||
<p>Having a consistent language in Software Architecture is beneficial when communicating with stakeholders and clarifying consistent patterns and principles that guide the development of software products.</p>
|
||||
|
||||
<Posts posts={posts} title="Previously..." />
|
||||
<hr />
|
||||
<em><a href="https://nownownow.com/about">About now pages</a></em>
|
||||
|
|
|
@ -7,7 +7,7 @@ const description = "I have been living now in Amsterdam for a little over a yea
|
|||
|
||||
<Layout title={title} description={description}>
|
||||
<main>
|
||||
<h1><span class="text-gradient">The Fediverse and Other Passion Projects</span></h1>
|
||||
<h1><span class="text-gradient">{title}</span></h1>
|
||||
<p>
|
||||
I have been living now in Amsterdam for a little over a year with my wife and son.
|
||||
</p>
|
||||
|
|
66
src/pages/now/and-then/posts/06-23-2023.astro
Normal file
66
src/pages/now/and-then/posts/06-23-2023.astro
Normal file
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
import Layout from "../../../../layouts/Layout.astro";
|
||||
import Footer from "../../../../components/Footer.astro";
|
||||
const title = "Building a Cozy Web without borders...";
|
||||
const description = "A project that aims to be a modern-day reading assistant"
|
||||
---
|
||||
|
||||
<Layout title={title} description={description}>
|
||||
<main>
|
||||
<h1><span class="text-gradient">{title}</span></h1>
|
||||
<p>
|
||||
Recently started a new project that aims to be a modern-day reading assistant, called <a href="https://ayco.io/gh/cozy">Cozy 🧸</a>.
|
||||
</p>
|
||||
<p>
|
||||
The full motivation as of the moment, I've written on <a href="https://ayos.blog/building-a-cozy-web/">my blog</a>.
|
||||
</p>
|
||||
<p>
|
||||
Also started exploring ways to interact on the web without being confined on a centralized solution that big tech companies have lured us into.
|
||||
</p>
|
||||
<p>
|
||||
I mean protocols that allow websites and people to exchange messages with each other without borders, like <a href="https://www.w3.org/TR/webmention/">webmention</a>, <a href="https://www.w3.org/TR/activitypub/">activitypub</a>, and the likes.
|
||||
</p>
|
||||
<Footer />
|
||||
</main>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
main {
|
||||
margin: auto;
|
||||
padding: 1em;
|
||||
max-width: var(--content-width);
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
font-weight: 900;
|
||||
background-image: var(--ayo-gradient);
|
||||
animation: pulse 4s ease-in-out infinite;
|
||||
background-size: 500% 500%;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-size: 100% 200%;
|
||||
background-position-y: 100%;
|
||||
border-radius: 0.4rem;
|
||||
}
|
||||
|
||||
.highlighted-content {
|
||||
margin: 1rem 0;
|
||||
background: #4f39fa;
|
||||
padding: 1rem;
|
||||
border-radius: 0.4rem;
|
||||
color: var(--color-bg);
|
||||
}
|
||||
|
||||
.highlighted-content code {
|
||||
font-size: var(--font-size-base);
|
||||
border: 0.1em solid var(--color-border);
|
||||
border-radius: 4px;
|
||||
padding: 0.15em 0.25em;
|
||||
}
|
||||
|
||||
.link-card-grid {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
|
@ -11,10 +11,15 @@ import Card from "../components/Card.astro";
|
|||
<main>
|
||||
<h1>Fun <span class="text-gradient">Side Projects</span></h1>
|
||||
<p>See more of my previous projects at <a href="https://ayos.blog/projects">my blog</a>.</p>
|
||||
<ul role="list">
|
||||
<ul>
|
||||
<Card
|
||||
href="/stuff"
|
||||
title="Small Stuff 🧱"
|
||||
body="Building blocks for projects"
|
||||
/>
|
||||
<Card
|
||||
newTab
|
||||
href="https://cozy-reader.netlify.app"
|
||||
href="https://ayco.io/gh/cozy#readme"
|
||||
title="Cozy 🧸"
|
||||
body="Your modern-day reading assistant"
|
||||
/>
|
||||
|
@ -22,22 +27,22 @@ import Card from "../components/Card.astro";
|
|||
newTab
|
||||
href="https://kaboom.ayco.io"
|
||||
title="Kaboom!"
|
||||
body="A simple physics simulation with Matter.js 👨🏻🔬"
|
||||
body="Simple physics simulation with Matter.js 👨🏻🔬"
|
||||
/>
|
||||
<Card
|
||||
newTab
|
||||
href="https://mnswpr.com"
|
||||
title="Minesweeper"
|
||||
body="Recreated the classic game that Microsoft discontinued 💣"
|
||||
body="Recreated the classic game for the web 💣"
|
||||
/>
|
||||
<Card
|
||||
href="/showcase/astro-reactive-form"
|
||||
title="Astro Reactive Form"
|
||||
title="Reactive Form"
|
||||
body="The reactive form component for Astro 🔥"
|
||||
/>
|
||||
<Card
|
||||
href="/showcase/astro-github-stats"
|
||||
title="Astro GitHub Stats"
|
||||
title="GitHub Stats"
|
||||
body="Embed GitHub stats on your Astro page ✨"
|
||||
/>
|
||||
</ul>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import Layout from "../../layouts/Layout.astro";
|
||||
import Footer from "../../components/Footer.astro";
|
||||
|
||||
import Form, { ControlConfig, FormGroup } from "@astro-reactive/form";
|
||||
import Form, { type ControlConfig, FormGroup } from "@astro-reactive/form";
|
||||
import { Validators } from "@astro-reactive/validator";
|
||||
|
||||
const simpleForm = new FormGroup([
|
||||
|
|
|
@ -10,7 +10,7 @@ import Footer from "../components/Footer.astro";
|
|||
>
|
||||
<main>
|
||||
<h1>Social <span class="text-gradient">Links</span></h1>
|
||||
<ul role="list" class="link-card-grid">
|
||||
<ul class="link-card-grid">
|
||||
<Card
|
||||
newTab={true}
|
||||
rel="me"
|
||||
|
|
45
src/pages/stuff.astro
Normal file
45
src/pages/stuff.astro
Normal file
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
import Layout from "../layouts/Layout.astro";
|
||||
import Footer from "../components/Footer.astro";
|
||||
import Card from "../components/Card.astro";
|
||||
---
|
||||
|
||||
<Layout
|
||||
title="Stuff: Smaller Building Blocks"
|
||||
description="See demos of side projects Ayo Ayco created"
|
||||
>
|
||||
<main>
|
||||
<h1 class="text-gradient">Stuff</h1>
|
||||
<p>Because software is not just a huge pile of code, but a combination of small, reusable stuff...</p>
|
||||
<ul>
|
||||
<Card
|
||||
newTab
|
||||
href="https://ayco.io/n/web-component-base"
|
||||
title="Web Component Base"
|
||||
body="This provides a minimal vanilla JS base class that aims to reduce the complexity of creating reactive custom elements."
|
||||
/>
|
||||
<Card
|
||||
newTab
|
||||
href="https://ayco.io/n/@ayco/astro-resume"
|
||||
title="Astro Resume"
|
||||
body="Utilities for serializing data from server for use in the client with types preserved across components."
|
||||
/>
|
||||
<Card
|
||||
newTab
|
||||
href="https://ayco.io/n/generate-timezone-json"
|
||||
title="Time Zone JSON Generator"
|
||||
body="Generate a JSON file containing time zones from the official IANA Database or your own zone.tab file"
|
||||
/>
|
||||
</ul>
|
||||
<Footer />
|
||||
</main>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
ul {
|
||||
list-style: none;
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
Loading…
Reference in a new issue