├── public ├── robots.txt ├── zaggonaut.png ├── michael-dam-unsplash.webp └── favicon.svg ├── images └── README.png ├── .vscode ├── settings.json ├── extensions.json └── launch.json ├── src ├── components │ ├── common │ │ ├── Section.astro │ │ └── Anchor.astro │ ├── home │ │ ├── Hero.astro │ │ ├── FeaturedArticles.astro │ │ └── FeaturedProjects.astro │ ├── ArticleSnippet.astro │ ├── Prose.astro │ ├── ProjectSnippet.astro │ ├── ThemeToggle.astro │ ├── Header.astro │ └── Footer.astro ├── lib │ ├── types.ts │ └── utils.ts ├── pages │ ├── projects │ │ ├── [id].astro │ │ └── index.astro │ ├── blog │ │ ├── [id].astro │ │ └── index.astro │ ├── 404.astro │ └── index.astro ├── layouts │ ├── Layout.astro │ ├── BlogLayout.astro │ └── ProjectLayout.astro ├── styles │ └── global.css └── content.config.ts ├── astro.config.mjs ├── tsconfig.json ├── .gitignore ├── package.json ├── content ├── projects │ └── zaggonaut.md ├── configuration.toml └── blogs │ └── html-intro.md ├── LICENSE.md └── README.md /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / -------------------------------------------------------------------------------- /images/README.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RATIU5/zaggonaut/HEAD/images/README.png -------------------------------------------------------------------------------- /public/zaggonaut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RATIU5/zaggonaut/HEAD/public/zaggonaut.png -------------------------------------------------------------------------------- /public/michael-dam-unsplash.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RATIU5/zaggonaut/HEAD/public/michael-dam-unsplash.webp -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "Frontmatter", 4 | "opsz", 5 | "Zaggonaut" 6 | ] 7 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /src/components/common/Section.astro: -------------------------------------------------------------------------------- 1 | --- 2 | const { class: className } = Astro.props; 3 | --- 4 | 5 |
6 | 7 |
8 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /astro.config.mjs: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | import { defineConfig } from "astro/config"; 3 | import tailwindcss from "@tailwindcss/vite"; 4 | 5 | // https://astro.build/config 6 | export default defineConfig({ 7 | vite: { 8 | plugins: [tailwindcss()], 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /src/lib/types.ts: -------------------------------------------------------------------------------- 1 | import type { CollectionEntry } from "astro:content"; 2 | 3 | export type ArticleFrontmatter = CollectionEntry<"blog">["data"] & { 4 | url: string; 5 | }; 6 | 7 | export type ProjectFrontmatter = CollectionEntry<"project">["data"] & { 8 | url: string; 9 | }; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "include": [".astro/types.d.ts", "**/*"], 4 | "exclude": ["dist"], 5 | "compilerOptions": { 6 | "allowImportingTsExtensions": true, 7 | "allowJs": true, 8 | "strictNullChecks": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | 23 | # jetbrains setting folder 24 | .idea/ 25 | 26 | pnpm-lock.yaml 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zaggonaut", 3 | "type": "module", 4 | "private": true, 5 | "version": "0.0.1", 6 | "packageManager": "pnpm@10.6.0", 7 | "scripts": { 8 | "dev": "astro dev", 9 | "build": "astro build", 10 | "preview": "astro preview", 11 | "astro": "astro", 12 | "preinstall": "npx only-allow pnpm" 13 | }, 14 | "dependencies": { 15 | "@astrojs/tailwind": "^6.0.2", 16 | "@tailwindcss/typography": "^0.5.16", 17 | "@tailwindcss/vite": "^4.1.11", 18 | "astro": "^5.10.1", 19 | "tailwindcss": "^4.1.11", 20 | "toml": "^3.0.0" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^22.15.33" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/pages/projects/[id].astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCollection, render } from "astro:content"; 3 | import ProjectLayout from "../../layouts/ProjectLayout.astro"; 4 | 5 | export async function getStaticPaths() { 6 | const projects = await getCollection("project"); 7 | return projects.map((project) => ({ 8 | params: { id: project.data.slug }, 9 | props: { 10 | project: { 11 | ...project, 12 | data: { 13 | ...project.data, 14 | url: `/projects/${project.data.slug}`, 15 | }, 16 | }, 17 | }, 18 | })); 19 | } 20 | 21 | const { project } = Astro.props; 22 | const { Content } = await render(project); 23 | --- 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/components/home/Hero.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getConfigurationCollection } from "../../lib/utils"; 3 | 4 | const { data: config } = await getConfigurationCollection(); 5 | --- 6 | 7 |
8 | {`${config.hero.title} 13 |
14 |

17 | {config.hero.title} 18 |

19 |

22 |

23 |

24 |
25 |
26 | -------------------------------------------------------------------------------- /src/components/ArticleSnippet.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { processArticleDate } from "../lib/utils"; 3 | import Anchor from "./common/Anchor.astro"; 4 | 5 | export type Props = { 6 | title: string; 7 | description: string; 8 | url: string; 9 | duration?: string; 10 | timestamp?: Date; 11 | }; 12 | 13 | const { title, description, url, duration, timestamp } = Astro.props; 14 | --- 15 | 16 |
17 | 18 | {title} 19 | 20 |

21 | {description} 22 |

23 |
26 | {timestamp ?

{processArticleDate(timestamp)}

: null} 27 | {duration ?

{duration}

: null} 28 |
29 |
30 | -------------------------------------------------------------------------------- /src/pages/blog/[id].astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { getCollection, render } from "astro:content"; 3 | import BlogLayout from "../../layouts/BlogLayout.astro"; 4 | import { getConfigurationCollection } from "../../lib/utils"; 5 | 6 | export async function getStaticPaths() { 7 | const posts = await getCollection("blog"); 8 | const { data: config } = await getConfigurationCollection(); 9 | return posts.map((article) => ({ 10 | params: { id: article.data.slug }, 11 | props: { 12 | article: { 13 | ...article, 14 | data: { 15 | ...article.data, 16 | url: `${config.site.baseUrl}/blog/${article.data.slug}`, 17 | }, 18 | }, 19 | }, 20 | })); 21 | } 22 | 23 | const { article } = Astro.props; 24 | const { Content } = await render(article); 25 | --- 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/components/common/Anchor.astro: -------------------------------------------------------------------------------- 1 | --- 2 | export type Props = { 3 | url: string; 4 | class?: string; 5 | external?: boolean; 6 | "aria-label"?: string; 7 | }; 8 | 9 | const { url, external, class: className } = Astro.props; 10 | --- 11 | 12 | 21 | 22 | { 23 | external ? ( 24 | 29 | 34 | 35 | ) : null 36 | } 37 | 38 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /content/projects/zaggonaut.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Zaggonaut 3 | slug: zaggonaut 4 | description: A retro-inspired theme for Astro, built using TypeScript, TailwindCSS, and Astro. 5 | longDescription: Zaggonaut is a retro-inspired theme for Astro, built using TypeScript, TailwindCSS, and Astro. 6 | cardImage: "https://zaggonaut.dev/michael-dam-unsplash.webp" 7 | tags: ["astro", "portfolio", "open-source"] 8 | githubUrl: https://github.com/RATIU5/zaggonaut 9 | timestamp: 2025-02-24T02:39:03+00:00 10 | featured: true 11 | --- 12 | 13 | ## The Details 14 | 15 | Zaggonaut is a retro-inspired theme for Astro, built using TypeScript, TailwindCSS, and Astro. Use this theme to power your own personal website, blog, or portfolio with flexibility and customization. 16 | 17 | ## The Features 18 | 19 | - Content Collections 20 | - Dark & light mode 21 | - Customizable colors 22 | - 100 / 100 Lighthouse score 23 | - Fully accessible 24 | - Fully responsive 25 | - Type-safe 26 | 27 | ## The Future 28 | 29 | Check out [the theme website](https://zaggonaut.dev) to see it in action! -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 RATIU5 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/components/home/FeaturedArticles.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { ArticleFrontmatter } from "../../lib/types"; 3 | import { getConfigurationCollection } from "../../lib/utils"; 4 | import ArticleSnippet from "../ArticleSnippet.astro"; 5 | import Anchor from "../common/Anchor.astro"; 6 | 7 | type Props = { 8 | featuredArticles: Array; 9 | } 10 | 11 | 12 | const { featuredArticles } = Astro.props; 13 | const { data: config } = await getConfigurationCollection(); 14 | --- 15 | 16 |
17 |

{config.texts.articlesName}

18 | {config.texts.viewAll} 19 |
20 | -------------------------------------------------------------------------------- /src/components/home/FeaturedProjects.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { ProjectFrontmatter } from "../../lib/types"; 3 | import { getConfigurationCollection } from "../../lib/utils"; 4 | import Anchor from "../common/Anchor.astro"; 5 | import ProjectSnippet from "../ProjectSnippet.astro"; 6 | 7 | type Props = { 8 | featuredProjects: Array; 9 | } 10 | 11 | const { featuredProjects } = Astro.props; 12 | const { data: config } = await getConfigurationCollection(); 13 | --- 14 | 15 |
16 |

{config.texts.projectsName}

17 | {config.texts.viewAll} 18 |
19 | -------------------------------------------------------------------------------- /src/components/Prose.astro: -------------------------------------------------------------------------------- 1 | --- 2 | type Props = { 3 | class?: string; 4 | }; 5 | 6 | const { class: customClass } = Astro.props; 7 | --- 8 | 9 |
13 | 14 |
15 | -------------------------------------------------------------------------------- /src/components/ProjectSnippet.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Anchor from "./common/Anchor.astro"; 3 | 4 | export type Props = { 5 | title: string; 6 | description: string; 7 | url: string; 8 | githubUrl?: string; 9 | liveUrl?: string; 10 | tags: string[]; 11 | }; 12 | 13 | const { title, description, url, githubUrl, liveUrl, tags } = Astro.props; 14 | --- 15 | 16 |
17 |
18 | 19 | {title} 20 | 21 |
22 | { 23 | githubUrl ? ( 24 | 25 | GitHub 26 | 27 | ) : null 28 | } 29 | { 30 | liveUrl ? ( 31 | 32 | Live 33 | 34 | ) : null 35 | } 36 |
37 |
38 |

39 | {description} 40 |

41 |
42 | { 43 | tags.map((tag) => ( 44 | 45 | {tag} 46 | 47 | )) 48 | } 49 |
50 |
51 | -------------------------------------------------------------------------------- /src/layouts/Layout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Footer from "../components/Footer.astro"; 3 | import Header from "../components/Header.astro"; 4 | import "../styles/global.css"; 5 | --- 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 40 | 41 | 42 | 43 | 44 |
45 |
46 | 47 |
48 |