update prettier and add eslint
This commit is contained in:
@@ -3,4 +3,4 @@
|
|||||||
.gitea
|
.gitea
|
||||||
.vscode
|
.vscode
|
||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
|
@@ -75,7 +75,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
url: '${{ secrets.NTFY_URL }}'
|
url: '${{ secrets.NTFY_URL }}'
|
||||||
topic: '${{ secrets.NTFY_TOPIC }}'
|
topic: '${{ secrets.NTFY_TOPIC }}'
|
||||||
title: "Gitea Action"
|
title: 'Gitea Action'
|
||||||
priority: 3
|
priority: 3
|
||||||
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
|
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
|
||||||
tags: action,successfully,completed
|
tags: action,successfully,completed
|
||||||
@@ -88,7 +88,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
url: '${{ secrets.NTFY_URL }}'
|
url: '${{ secrets.NTFY_URL }}'
|
||||||
topic: '${{ secrets.NTFY_TOPIC }}'
|
topic: '${{ secrets.NTFY_TOPIC }}'
|
||||||
title: "Gitea Action"
|
title: 'Gitea Action'
|
||||||
priority: 4
|
priority: 4
|
||||||
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
|
headers: '{"Authorization": "Bearer ${{ secrets.NTFY_CRED }}"}'
|
||||||
tags: action,failed
|
tags: action,failed
|
||||||
|
@@ -2,7 +2,7 @@ name: tag-old-issues
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "@daily"
|
- cron: '@daily'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
tag-old-issues:
|
tag-old-issues:
|
||||||
|
@@ -30,5 +30,8 @@ jobs:
|
|||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: pnpm install
|
run: pnpm install
|
||||||
|
|
||||||
|
- name: Lint Code
|
||||||
|
run: pnpm lint
|
||||||
|
|
||||||
- name: Build Project
|
- name: Build Project
|
||||||
run: pnpm build
|
run: pnpm build
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,4 +24,3 @@ pnpm-debug.log*
|
|||||||
# ide
|
# ide
|
||||||
.vscode/
|
.vscode/
|
||||||
site-profile.code-workspace
|
site-profile.code-workspace
|
||||||
.pre-commit-config.yaml
|
|
||||||
|
1
.npmrc
1
.npmrc
@@ -1,3 +1,2 @@
|
|||||||
engine-strict=true
|
engine-strict=true
|
||||||
save-exact=true
|
save-exact=true
|
||||||
|
|
||||||
|
17
.prettierrc
17
.prettierrc
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 100,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"trailingComma": "es5",
|
|
||||||
"useTabs": false,
|
|
||||||
"plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": "*.astro",
|
|
||||||
"options": {
|
|
||||||
"parser": "astro"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@@ -33,4 +33,4 @@ ENV DIRECTUS_URL=https://directus.alexlebens.dev
|
|||||||
ENV PORT=4321
|
ENV PORT=4321
|
||||||
|
|
||||||
EXPOSE $PORT
|
EXPOSE $PORT
|
||||||
CMD ["node", "./dist/server/entry.mjs"]
|
CMD ["node", "./dist/server/entry.mjs"]
|
||||||
|
14
README.md
14
README.md
@@ -21,7 +21,7 @@ Personal site used for information about myself and blog.
|
|||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
- Node.js 16+ and pnpm/yarn
|
- Node.js 22+ and pnpm
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
@@ -30,22 +30,18 @@ Personal site used for information about myself and blog.
|
|||||||
git clone https://gitea.alexlebens.dev/alexlebens/site-profile
|
git clone https://gitea.alexlebens.dev/alexlebens/site-profile
|
||||||
|
|
||||||
# Navigate to project directory
|
# Navigate to project directory
|
||||||
cd astro-blog
|
cd site-profile
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
pnpm install
|
pnpm install
|
||||||
|
|
||||||
# Create .env file from template
|
|
||||||
cp .env.example .env
|
|
||||||
|
|
||||||
# Edit .env with your information
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Development
|
### Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Start development server
|
# Start development server
|
||||||
pnpm run dev
|
pnpm dev
|
||||||
|
|
||||||
# Open browser at http://localhost:4321
|
# Open browser at http://localhost:4321
|
||||||
```
|
```
|
||||||
@@ -54,10 +50,10 @@ pnpm run dev
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Create production build
|
# Create production build
|
||||||
pnpm run build
|
pnpm build
|
||||||
|
|
||||||
# Preview production build
|
# Preview production build
|
||||||
pnpm run preview
|
pnpm preview
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
@@ -16,14 +16,14 @@ export default defineConfig({
|
|||||||
integrations: [tailwindcss(), react()],
|
integrations: [tailwindcss(), react()],
|
||||||
|
|
||||||
plugins: {
|
plugins: {
|
||||||
"@tailwindcss/postcss": {},
|
'@tailwindcss/postcss': {},
|
||||||
},
|
},
|
||||||
|
|
||||||
vite: {
|
vite: {
|
||||||
plugins: [tailwindcss()]
|
plugins: [tailwindcss()],
|
||||||
},
|
},
|
||||||
|
|
||||||
adapter: node({
|
adapter: node({
|
||||||
mode: 'standalone'
|
mode: 'standalone',
|
||||||
})
|
}),
|
||||||
});
|
});
|
||||||
|
11
eslint.config.mjs
Normal file
11
eslint.config.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import eslintPluginAstro from 'eslint-plugin-astro';
|
||||||
|
import eslintConfigPrettier from "eslint-config-prettier/flat";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
...eslintPluginAstro.configs.recommended,
|
||||||
|
eslintConfigPrettier,
|
||||||
|
{
|
||||||
|
rules: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
13
package.json
13
package.json
@@ -7,7 +7,9 @@
|
|||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"format": "prettier . --write",
|
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,md,mdx,astro}\"",
|
||||||
|
"lint": "eslint \"src/**/*.{js,ts,jsx,tsx,astro}\"",
|
||||||
|
"lint:fix": "eslint --fix \"src/**/*.{js,ts,jsx,tsx,astro}\"",
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -32,8 +34,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/typography": "^0.5.16",
|
"@tailwindcss/typography": "^0.5.16",
|
||||||
|
"@typescript-eslint/parser": "8.34.0",
|
||||||
|
"eslint": "9.28.0",
|
||||||
|
"eslint-config-prettier": "10.1.5",
|
||||||
|
"eslint-plugin-astro": "1.3.1",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-astro": "^0.14.0",
|
"prettier-plugin-astro": "^0.14.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.6.0"
|
"prettier-plugin-tailwindcss": "^0.6.12",
|
||||||
|
"typescript-eslint": "8.34.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1075
pnpm-lock.yaml
generated
1075
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
/** @type {import('postcss-load-config').Config} */
|
/** @type {import('postcss-load-config').Config} */
|
||||||
const config = {
|
const config = {
|
||||||
plugins: {
|
plugins: {
|
||||||
"@tailwindcss/postcss": {},
|
'@tailwindcss/postcss': {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
'postcss-preset-env': {
|
'postcss-preset-env': {
|
||||||
features: {
|
features: {
|
||||||
|
23
prettier.config.mjs
Normal file
23
prettier.config.mjs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/** @type {import("prettier").Config} */
|
||||||
|
const config = {
|
||||||
|
printWidth: 100,
|
||||||
|
semi: true,
|
||||||
|
singleQuote: true,
|
||||||
|
tabWidth: 2,
|
||||||
|
trailingComma: 'es5',
|
||||||
|
useTabs: false,
|
||||||
|
plugins: [
|
||||||
|
'prettier-plugin-astro',
|
||||||
|
'prettier-plugin-tailwindcss',
|
||||||
|
],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: '*.astro',
|
||||||
|
options: {
|
||||||
|
parser: 'astro',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
@@ -6,4 +6,3 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 713 B After Width: | Height: | Size: 712 B |
@@ -5,17 +5,17 @@
|
|||||||
<div class="theme-transition-all fixed inset-0 -z-10 overflow-hidden">
|
<div class="theme-transition-all fixed inset-0 -z-10 overflow-hidden">
|
||||||
<!-- Dot pattern background -->
|
<!-- Dot pattern background -->
|
||||||
<div
|
<div
|
||||||
class="bg-grid-pattern theme-transition-bg absolute inset-0 bg-[center_top_-1px] [mask-image:radial-gradient(white,transparent_85%)]"
|
class="bg-grid-pattern theme-transition-bg absolute inset-0 [mask-image:radial-gradient(white,transparent_85%)] bg-[center_top_-1px]"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Ambient glow effects -->
|
<!-- Ambient glow effects -->
|
||||||
<div
|
<div
|
||||||
class="animate-glow theme-transition-bg absolute left-1/4 top-1/4 h-96 w-96 -translate-x-1/2 -translate-y-1/2 rounded-full bg-zinc-400/20 opacity-50 blur-3xl dark:bg-zinc-500/20"
|
class="animate-glow theme-transition-bg absolute top-1/4 left-1/4 h-96 w-96 -translate-x-1/2 -translate-y-1/2 rounded-full bg-zinc-400/20 opacity-50 blur-3xl dark:bg-zinc-500/20"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-glow animation-delay-1000 theme-transition-bg absolute bottom-1/3 right-1/4 h-64 w-64 translate-x-1/2 translate-y-1/2 rounded-full bg-zinc-300/20 opacity-40 blur-3xl dark:bg-zinc-600/20"
|
class="animate-glow animation-delay-1000 theme-transition-bg absolute right-1/4 bottom-1/3 h-64 w-64 translate-x-1/2 translate-y-1/2 rounded-full bg-zinc-300/20 opacity-40 blur-3xl dark:bg-zinc-600/20"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ const socialLinks = [
|
|||||||
>
|
>
|
||||||
<div class="pointer-events-none absolute inset-0 overflow-hidden">
|
<div class="pointer-events-none absolute inset-0 overflow-hidden">
|
||||||
<div
|
<div
|
||||||
class="theme-transition-all animate-float-slow absolute -right-40 -top-40 h-80 w-80 rounded-full bg-zinc-100 opacity-50 blur-3xl dark:bg-zinc-800/30"
|
class="theme-transition-all animate-float-slow absolute -top-40 -right-40 h-80 w-80 rounded-full bg-zinc-100 opacity-50 blur-3xl dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -41,12 +41,12 @@ const socialLinks = [
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="theme-transition-all animate-float-slow animation-delay-1000 absolute left-1/4 top-20 h-40 w-40 rounded-full bg-zinc-200/50 opacity-30 blur-2xl dark:bg-zinc-700/20"
|
class="theme-transition-all animate-float-slow animation-delay-1000 absolute top-20 left-1/4 h-40 w-40 rounded-full bg-zinc-200/50 opacity-30 blur-2xl dark:bg-zinc-700/20"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative px-4 pb-12 pt-16 sm:px-6">
|
<div class="relative px-4 pt-16 pb-12 sm:px-6">
|
||||||
<div class="mx-auto max-w-4xl">
|
<div class="mx-auto max-w-4xl">
|
||||||
<!-- Main footer content -->
|
<!-- Main footer content -->
|
||||||
<div class="grid grid-cols-1 gap-10 md:grid-cols-12">
|
<div class="grid grid-cols-1 gap-10 md:grid-cols-12">
|
||||||
@@ -108,7 +108,7 @@ const socialLinks = [
|
|||||||
<!-- Quick links -->
|
<!-- Quick links -->
|
||||||
<div class="col-span-1 md:col-span-3">
|
<div class="col-span-1 md:col-span-3">
|
||||||
<h3
|
<h3
|
||||||
class="theme-transition-color relative inline-block pb-2 text-sm font-semibold uppercase tracking-wider text-zinc-900 after:absolute after:bottom-0 after:left-0 after:h-0.5 after:w-8 after:bg-zinc-300 after:content-[''] dark:text-zinc-100 dark:after:bg-zinc-700"
|
class="theme-transition-color relative inline-block pb-2 text-sm font-semibold tracking-wider text-zinc-900 uppercase after:absolute after:bottom-0 after:left-0 after:h-0.5 after:w-8 after:bg-zinc-300 after:content-[''] dark:text-zinc-100 dark:after:bg-zinc-700"
|
||||||
>
|
>
|
||||||
Navigation
|
Navigation
|
||||||
</h3>
|
</h3>
|
||||||
|
@@ -19,7 +19,7 @@ const currentPath = pathname.slice(1);
|
|||||||
---
|
---
|
||||||
|
|
||||||
<header
|
<header
|
||||||
class="fixed left-0 right-0 top-0 z-40 border-b border-zinc-100 bg-white py-4 dark:border-zinc-800 dark:bg-zinc-900"
|
class="fixed top-0 right-0 left-0 z-40 border-b border-zinc-100 bg-white py-4 dark:border-zinc-800 dark:bg-zinc-900"
|
||||||
>
|
>
|
||||||
<div class="mx-auto flex max-w-3xl items-center justify-between px-4">
|
<div class="mx-auto flex max-w-3xl items-center justify-between px-4">
|
||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
|
@@ -94,7 +94,7 @@ const encodedUrl = encodeURIComponent(url);
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
id="copy-tooltip"
|
id="copy-tooltip"
|
||||||
class="absolute -top-8 left-1/2 -translate-x-1/2 transform whitespace-nowrap rounded bg-zinc-800 px-2 py-1 text-xs text-white opacity-0 transition-opacity duration-300 dark:bg-zinc-700"
|
class="absolute -top-8 left-1/2 -translate-x-1/2 transform rounded bg-zinc-800 px-2 py-1 text-xs whitespace-nowrap text-white opacity-0 transition-opacity duration-300 dark:bg-zinc-700"
|
||||||
>
|
>
|
||||||
Copied!
|
Copied!
|
||||||
</span>
|
</span>
|
||||||
|
@@ -5,14 +5,14 @@
|
|||||||
<button
|
<button
|
||||||
id="theme-toggle"
|
id="theme-toggle"
|
||||||
data-theme-toggle
|
data-theme-toggle
|
||||||
class="group relative touch-manipulation overflow-hidden rounded-full p-1.5 transition-all duration-300 hover:bg-zinc-100 focus:outline-none focus:ring-2 focus:ring-zinc-300 dark:hover:bg-zinc-800 dark:focus:ring-zinc-700 sm:p-2"
|
class="group relative touch-manipulation overflow-hidden rounded-full p-1.5 transition-all duration-300 hover:bg-zinc-100 focus:ring-2 focus:ring-zinc-300 focus:outline-none sm:p-2 dark:hover:bg-zinc-800 dark:focus:ring-zinc-700"
|
||||||
aria-label="Toggle dark mode"
|
aria-label="Toggle dark mode"
|
||||||
>
|
>
|
||||||
<div class="relative z-10 flex h-5 w-5 items-center justify-center">
|
<div class="relative z-10 flex h-5 w-5 items-center justify-center">
|
||||||
<!-- Sun icon -->
|
<!-- Sun icon -->
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="icon-light absolute h-5 w-5 rotate-0 scale-100 text-zinc-800 transition-all duration-500 dark:-rotate-90 dark:scale-0 dark:text-zinc-200"
|
class="icon-light absolute h-5 w-5 scale-100 rotate-0 text-zinc-800 transition-all duration-500 dark:scale-0 dark:-rotate-90 dark:text-zinc-200"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<!-- Moon icon -->
|
<!-- Moon icon -->
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="icon-dark absolute h-5 w-5 rotate-90 scale-0 text-zinc-800 transition-all duration-500 dark:rotate-0 dark:scale-100 dark:text-zinc-200"
|
class="icon-dark absolute h-5 w-5 scale-0 rotate-90 text-zinc-800 transition-all duration-500 dark:scale-100 dark:rotate-0 dark:text-zinc-200"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
@@ -30,10 +30,10 @@ try {
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Layout title={post.title} description={post.description}>
|
<Layout title={post.title} description={post.description}>
|
||||||
<article class="prose prose-zinc mx-auto max-w-4xl dark:prose-invert lg:prose-lg">
|
<article class="prose prose-zinc dark:prose-invert lg:prose-lg mx-auto max-w-4xl">
|
||||||
<div class="mb-12">
|
<div class="mb-12">
|
||||||
<h1
|
<h1
|
||||||
class="mb-4 text-4xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:text-5xl"
|
class="mb-4 text-4xl font-bold tracking-tight text-zinc-900 sm:text-5xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
{post.title}
|
{post.title}
|
||||||
</h1>
|
</h1>
|
||||||
@@ -76,7 +76,7 @@ try {
|
|||||||
|
|
||||||
{
|
{
|
||||||
post.updated_date && (
|
post.updated_date && (
|
||||||
<div class="mt-8 text-sm italic text-zinc-500 dark:text-zinc-400">
|
<div class="mt-8 text-sm text-zinc-500 italic dark:text-zinc-400">
|
||||||
Last updated on <FormattedDate date={post.updated_date} />
|
Last updated on <FormattedDate date={post.updated_date} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@@ -9,11 +9,11 @@ import Layout from '../layouts/Layout.astro';
|
|||||||
<!-- Animated background elements -->
|
<!-- Animated background elements -->
|
||||||
<div class="absolute inset-0 overflow-hidden">
|
<div class="absolute inset-0 overflow-hidden">
|
||||||
<div
|
<div
|
||||||
class="animate-blob absolute -left-20 -top-20 h-64 w-64 rounded-full bg-zinc-100 opacity-50 blur-3xl dark:bg-zinc-800/50"
|
class="animate-blob absolute -top-20 -left-20 h-64 w-64 rounded-full bg-zinc-100 opacity-50 blur-3xl dark:bg-zinc-800/50"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-blob animation-delay-2000 absolute right-1/4 top-1/2 h-96 w-96 rounded-full bg-zinc-200 opacity-30 blur-3xl dark:bg-zinc-800/30"
|
class="animate-blob animation-delay-2000 absolute top-1/2 right-1/4 h-96 w-96 rounded-full bg-zinc-200 opacity-30 blur-3xl dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -26,14 +26,14 @@ import Layout from '../layouts/Layout.astro';
|
|||||||
<div class="relative z-10 mx-auto max-w-xl">
|
<div class="relative z-10 mx-auto max-w-xl">
|
||||||
<div class="glitch-wrapper">
|
<div class="glitch-wrapper">
|
||||||
<h1
|
<h1
|
||||||
class="glitch text-9xl font-bold leading-none text-zinc-900 dark:text-zinc-100 sm:text-[12rem]"
|
class="glitch text-9xl leading-none font-bold text-zinc-900 sm:text-[12rem] dark:text-zinc-100"
|
||||||
data-text="404"
|
data-text="404"
|
||||||
>
|
>
|
||||||
404
|
404
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="mt-6 text-2xl font-bold text-zinc-800 dark:text-zinc-200 sm:text-3xl">
|
<h2 class="mt-6 text-2xl font-bold text-zinc-800 sm:text-3xl dark:text-zinc-200">
|
||||||
Page Not Found
|
Page Not Found
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ import Layout from '../layouts/Layout.astro';
|
|||||||
<div
|
<div
|
||||||
class="mx-auto mt-16 max-w-md rounded-xl border border-zinc-100 bg-zinc-50 p-6 shadow-sm backdrop-blur-sm dark:border-zinc-700/50 dark:bg-zinc-800/50"
|
class="mx-auto mt-16 max-w-md rounded-xl border border-zinc-100 bg-zinc-50 p-6 shadow-sm backdrop-blur-sm dark:border-zinc-700/50 dark:bg-zinc-800/50"
|
||||||
>
|
>
|
||||||
<h3 class="text-sm font-medium uppercase tracking-wider text-zinc-500 dark:text-zinc-400">
|
<h3 class="text-sm font-medium tracking-wider text-zinc-500 uppercase dark:text-zinc-400">
|
||||||
Did you know?
|
Did you know?
|
||||||
</h3>
|
</h3>
|
||||||
<p class="mt-2 text-sm text-zinc-700 dark:text-zinc-300" id="fun-fact">
|
<p class="mt-2 text-sm text-zinc-700 dark:text-zinc-300" id="fun-fact">
|
||||||
|
@@ -22,18 +22,18 @@ const skills = await directus.request(
|
|||||||
<div class="relative mb-12 sm:mb-16 md:mb-20">
|
<div class="relative mb-12 sm:mb-16 md:mb-20">
|
||||||
<!-- Decorative elements -->
|
<!-- Decorative elements -->
|
||||||
<div
|
<div
|
||||||
class="animate-blob theme-transition-bg absolute -left-10 -top-10 h-36 w-36 rounded-full bg-zinc-100 opacity-30 blur-3xl dark:bg-zinc-800/30 sm:-left-20 sm:-top-20 sm:h-48 sm:w-48 md:h-72 md:w-72"
|
class="animate-blob theme-transition-bg absolute -top-10 -left-10 h-36 w-36 rounded-full bg-zinc-100 opacity-30 blur-3xl sm:-top-20 sm:-left-20 sm:h-48 sm:w-48 md:h-72 md:w-72 dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-blob animation-delay-2000 theme-transition-bg absolute -bottom-10 -right-10 h-36 w-36 rounded-full bg-zinc-200 opacity-30 blur-3xl dark:bg-zinc-800/30 sm:-bottom-20 sm:-right-20 sm:h-48 sm:w-48 md:h-72 md:w-72"
|
class="animate-blob animation-delay-2000 theme-transition-bg absolute -right-10 -bottom-10 h-36 w-36 rounded-full bg-zinc-200 opacity-30 blur-3xl sm:-right-20 sm:-bottom-20 sm:h-48 sm:w-48 md:h-72 md:w-72 dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative grid grid-cols-1 items-center gap-8 md:grid-cols-2 md:gap-12">
|
<div class="relative grid grid-cols-1 items-center gap-8 md:grid-cols-2 md:gap-12">
|
||||||
<div class="order-2 text-center md:order-1 md:text-left">
|
<div class="order-2 text-center md:order-1 md:text-left">
|
||||||
<h1
|
<h1
|
||||||
class="theme-transition-color mb-4 text-3xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:mb-6 sm:text-4xl md:text-5xl"
|
class="theme-transition-color mb-4 text-3xl font-bold tracking-tight text-zinc-900 sm:mb-6 sm:text-4xl md:text-5xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
Hello, I'm <span
|
Hello, I'm <span
|
||||||
class="theme-transition-all bg-gradient-to-r from-zinc-500 to-zinc-900 bg-clip-text text-transparent dark:from-zinc-300 dark:to-zinc-100"
|
class="theme-transition-all bg-gradient-to-r from-zinc-500 to-zinc-900 bg-clip-text text-transparent dark:from-zinc-300 dark:to-zinc-100"
|
||||||
@@ -42,7 +42,7 @@ const skills = await directus.request(
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
class="theme-transition-color mb-6 text-lg leading-relaxed text-zinc-600 dark:text-zinc-400 sm:mb-8 sm:text-xl"
|
class="theme-transition-color mb-6 text-lg leading-relaxed text-zinc-600 sm:mb-8 sm:text-xl dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{about.background}
|
{about.background}
|
||||||
</p>
|
</p>
|
||||||
@@ -56,7 +56,7 @@ const skills = await directus.request(
|
|||||||
|
|
||||||
<div class="relative order-1 md:order-2">
|
<div class="relative order-1 md:order-2">
|
||||||
<div
|
<div
|
||||||
class="theme-transition-all mx-auto aspect-square w-full max-w-[280px] overflow-hidden rounded-3xl border-4 border-white shadow-xl dark:border-zinc-800 sm:max-w-[320px] sm:border-8 sm:shadow-2xl md:max-w-md"
|
class="theme-transition-all mx-auto aspect-square w-full max-w-[280px] overflow-hidden rounded-3xl border-4 border-white shadow-xl sm:max-w-[320px] sm:border-8 sm:shadow-2xl md:max-w-md dark:border-zinc-800"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src=`${process.env.DIRECTUS_URL ?? "https://directus.alexlebens.dev"}/assets/${global.portrait}`
|
src=`${process.env.DIRECTUS_URL ?? "https://directus.alexlebens.dev"}/assets/${global.portrait}`
|
||||||
@@ -68,7 +68,7 @@ const skills = await directus.request(
|
|||||||
|
|
||||||
<!-- Decorative elements -->
|
<!-- Decorative elements -->
|
||||||
<div
|
<div
|
||||||
class="theme-transition-all absolute -bottom-4 -right-4 flex h-16 w-16 items-center justify-center rounded-full border-2 border-white bg-zinc-100 shadow-lg dark:border-zinc-900 dark:bg-zinc-800 sm:-bottom-6 sm:-right-6 sm:h-20 sm:w-20 sm:border-4 md:h-24 md:w-24"
|
class="theme-transition-all absolute -right-4 -bottom-4 flex h-16 w-16 items-center justify-center rounded-full border-2 border-white bg-zinc-100 shadow-lg sm:-right-6 sm:-bottom-6 sm:h-20 sm:w-20 sm:border-4 md:h-24 md:w-24 dark:border-zinc-900 dark:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<span class="text-2xl sm:text-3xl">👋</span>
|
<span class="text-2xl sm:text-3xl">👋</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -80,18 +80,18 @@ const skills = await directus.request(
|
|||||||
<div class="theme-transition-all mb-16 sm:mb-20 md:mb-24">
|
<div class="theme-transition-all mb-16 sm:mb-20 md:mb-24">
|
||||||
<div class="mx-auto max-w-3xl">
|
<div class="mx-auto max-w-3xl">
|
||||||
<h2
|
<h2
|
||||||
class="theme-transition-color mb-6 flex items-center justify-center text-2xl font-bold text-zinc-900 dark:text-zinc-100 sm:mb-8 sm:text-3xl md:justify-start"
|
class="theme-transition-color mb-6 flex items-center justify-center text-2xl font-bold text-zinc-900 sm:mb-8 sm:text-3xl md:justify-start dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="theme-transition-bg mr-4 hidden h-1 w-8 bg-zinc-300 dark:bg-zinc-700 sm:inline-block sm:w-12"
|
class="theme-transition-bg mr-4 hidden h-1 w-8 bg-zinc-300 sm:inline-block sm:w-12 dark:bg-zinc-700"
|
||||||
></span>
|
></span>
|
||||||
About Me
|
About Me
|
||||||
<span
|
<span
|
||||||
class="theme-transition-bg ml-4 hidden h-1 w-8 bg-zinc-300 dark:bg-zinc-700 sm:inline-block sm:w-12"
|
class="theme-transition-bg ml-4 hidden h-1 w-8 bg-zinc-300 sm:inline-block sm:w-12 dark:bg-zinc-700"
|
||||||
></span>
|
></span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="theme-transition-all prose prose-zinc max-w-none dark:prose-invert">
|
<div class="theme-transition-all prose prose-zinc dark:prose-invert max-w-none">
|
||||||
<p class="theme-transition-color mb-4 text-base leading-relaxed sm:mb-6 sm:text-lg">
|
<p class="theme-transition-color mb-4 text-base leading-relaxed sm:mb-6 sm:text-lg">
|
||||||
{about.experience}
|
{about.experience}
|
||||||
</p>
|
</p>
|
||||||
@@ -110,7 +110,7 @@ const skills = await directus.request(
|
|||||||
<!-- Skills Section -->
|
<!-- Skills Section -->
|
||||||
<div class="theme-transition-all mb-16 sm:mb-20 md:mb-24">
|
<div class="theme-transition-all mb-16 sm:mb-20 md:mb-24">
|
||||||
<h2
|
<h2
|
||||||
class="theme-transition-color mb-8 text-center text-2xl font-bold text-zinc-900 dark:text-zinc-100 sm:mb-12 sm:text-3xl"
|
class="theme-transition-color mb-8 text-center text-2xl font-bold text-zinc-900 sm:mb-12 sm:text-3xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
Tech Stack
|
Tech Stack
|
||||||
</h2>
|
</h2>
|
||||||
@@ -122,34 +122,34 @@ const skills = await directus.request(
|
|||||||
skills.map((skill, index) => (
|
skills.map((skill, index) => (
|
||||||
<div
|
<div
|
||||||
key={`${skill.title}-${index}`}
|
key={`${skill.title}-${index}`}
|
||||||
class="skill-card theme-transition-element mx-2 min-w-[220px] transform rounded-xl border border-zinc-200 bg-white transition-all duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-300 hover:shadow-xl dark:border-zinc-700 dark:bg-zinc-800/50 dark:hover:border-zinc-600 sm:mx-4 sm:min-w-[280px]"
|
class="skill-card theme-transition-element mx-2 min-w-[220px] transform rounded-xl border border-zinc-200 bg-white transition-all duration-300 hover:-translate-y-2 hover:scale-105 hover:border-zinc-300 hover:shadow-xl sm:mx-4 sm:min-w-[280px] dark:border-zinc-700 dark:bg-zinc-800/50 dark:hover:border-zinc-600"
|
||||||
>
|
>
|
||||||
<div class="p-4 sm:p-6">
|
<div class="p-4 sm:p-6">
|
||||||
<div class="mb-4 flex items-center justify-between sm:mb-6">
|
<div class="mb-4 flex items-center justify-between sm:mb-6">
|
||||||
<div class="flex items-center gap-2 sm:gap-4">
|
<div class="flex items-center gap-2 sm:gap-4">
|
||||||
<div class="theme-transition-bg theme-transition-color flex h-8 w-8 transform items-center justify-center rounded-lg bg-zinc-100 text-zinc-800 transition-transform group-hover:rotate-12 dark:bg-zinc-800 dark:text-zinc-200 sm:h-12 sm:w-12">
|
<div class="theme-transition-bg theme-transition-color flex h-8 w-8 transform items-center justify-center rounded-lg bg-zinc-100 text-zinc-800 transition-transform group-hover:rotate-12 sm:h-12 sm:w-12 dark:bg-zinc-800 dark:text-zinc-200">
|
||||||
<skill.icon
|
<skill.icon
|
||||||
size={20}
|
size={20}
|
||||||
className="sm:text-2xl transform transition-all hover:scale-125"
|
className="sm:text-2xl transform transition-all hover:scale-125"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="theme-transition-color text-base font-semibold text-zinc-900 dark:text-zinc-100 sm:text-xl">
|
<h3 class="theme-transition-color text-base font-semibold text-zinc-900 sm:text-xl dark:text-zinc-100">
|
||||||
{skill.title}
|
{skill.title}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<span class="theme-transition-all rounded-full bg-zinc-100 px-2 py-0.5 font-mono text-xs text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400 sm:px-2.5 sm:py-1 sm:text-sm">
|
<span class="theme-transition-all rounded-full bg-zinc-100 px-2 py-0.5 font-mono text-xs text-zinc-600 sm:px-2.5 sm:py-1 sm:text-sm dark:bg-zinc-800 dark:text-zinc-400">
|
||||||
{skill.level}%
|
{skill.level}%
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="theme-transition-bg relative h-1.5 w-full overflow-hidden rounded-full bg-zinc-100 dark:bg-zinc-700 sm:h-2">
|
<div class="theme-transition-bg relative h-1.5 w-full overflow-hidden rounded-full bg-zinc-100 sm:h-2 dark:bg-zinc-700">
|
||||||
<div
|
<div
|
||||||
class="progress-bar-animate theme-transition-bg absolute left-0 top-0 h-full rounded-full bg-gradient-to-r from-zinc-700 via-zinc-600 to-zinc-800 transition-all duration-1000 dark:from-zinc-300 dark:via-zinc-400 dark:to-zinc-200"
|
class="progress-bar-animate theme-transition-bg absolute top-0 left-0 h-full rounded-full bg-gradient-to-r from-zinc-700 via-zinc-600 to-zinc-800 transition-all duration-1000 dark:from-zinc-300 dark:via-zinc-400 dark:to-zinc-200"
|
||||||
style={`width: ${skill.level}%`}
|
style={`width: ${skill.level}%`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="theme-transition-color mt-1 flex justify-between font-mono text-[10px] text-zinc-400 dark:text-zinc-500 sm:mt-2 sm:text-xs">
|
<div class="theme-transition-color mt-1 flex justify-between font-mono text-[10px] text-zinc-400 sm:mt-2 sm:text-xs dark:text-zinc-500">
|
||||||
<span>Beginner</span>
|
<span>Beginner</span>
|
||||||
<span>Advanced</span>
|
<span>Advanced</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -161,11 +161,11 @@ const skills = await directus.request(
|
|||||||
|
|
||||||
<!-- Gradient overlays for smooth fade effect -->
|
<!-- Gradient overlays for smooth fade effect -->
|
||||||
<div
|
<div
|
||||||
class="theme-transition-bg absolute bottom-0 left-0 top-0 z-10 w-12 bg-gradient-to-r from-white to-transparent dark:from-zinc-900 sm:w-24"
|
class="theme-transition-bg absolute top-0 bottom-0 left-0 z-10 w-12 bg-gradient-to-r from-white to-transparent sm:w-24 dark:from-zinc-900"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="theme-transition-bg absolute bottom-0 right-0 top-0 z-10 w-12 bg-gradient-to-l from-white to-transparent dark:from-zinc-900 sm:w-24"
|
class="theme-transition-bg absolute top-0 right-0 bottom-0 z-10 w-12 bg-gradient-to-l from-white to-transparent sm:w-24 dark:from-zinc-900"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -174,12 +174,12 @@ const skills = await directus.request(
|
|||||||
<!-- Contact Section -->
|
<!-- Contact Section -->
|
||||||
<div class="theme-transition-all mx-auto max-w-3xl text-center">
|
<div class="theme-transition-all mx-auto max-w-3xl text-center">
|
||||||
<h2
|
<h2
|
||||||
class="theme-transition-color mb-4 text-2xl font-bold text-zinc-900 dark:text-zinc-100 sm:mb-6 sm:text-3xl"
|
class="theme-transition-color mb-4 text-2xl font-bold text-zinc-900 sm:mb-6 sm:text-3xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
Get in Touch
|
Get in Touch
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
class="theme-transition-color mb-6 text-base text-zinc-600 dark:text-zinc-400 sm:mb-8 sm:text-lg"
|
class="theme-transition-color mb-6 text-base text-zinc-600 sm:mb-8 sm:text-lg dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
I'm always open to new opportunities and collaborations. If you'd like to work together or
|
I'm always open to new opportunities and collaborations. If you'd like to work together or
|
||||||
just say hello, feel free to reach out.
|
just say hello, feel free to reach out.
|
||||||
@@ -187,7 +187,7 @@ const skills = await directus.request(
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
href=`mailto:${global.email}`
|
href=`mailto:${global.email}`
|
||||||
class="theme-transition-all inline-flex items-center justify-center rounded-lg bg-zinc-900 px-6 py-3 text-base font-medium text-zinc-100 transition-colors hover:bg-zinc-700 dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-300 sm:px-8 sm:py-4 sm:text-lg"
|
class="theme-transition-all inline-flex items-center justify-center rounded-lg bg-zinc-900 px-6 py-3 text-base font-medium text-zinc-100 transition-colors hover:bg-zinc-700 sm:px-8 sm:py-4 sm:text-lg dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-300"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@@ -43,23 +43,23 @@ const { post, nextPost, prevPost } = Astro.props;
|
|||||||
>
|
>
|
||||||
<!-- Main Content - Enhanced with better typography and spacing -->
|
<!-- Main Content - Enhanced with better typography and spacing -->
|
||||||
<div
|
<div
|
||||||
class="prose prose-sm prose-zinc max-w-none dark:prose-invert sm:prose-base prose-headings:scroll-mt-24 prose-headings:font-semibold prose-a:font-medium prose-a:text-zinc-800 prose-a:underline-offset-4 hover:prose-a:text-zinc-600 prose-img:rounded-xl dark:prose-a:text-zinc-300 dark:hover:prose-a:text-zinc-100"
|
class="prose prose-sm prose-zinc dark:prose-invert sm:prose-base prose-headings:scroll-mt-24 prose-headings:font-semibold prose-a:font-medium prose-a:text-zinc-800 prose-a:underline-offset-4 hover:prose-a:text-zinc-600 prose-img:rounded-xl dark:prose-a:text-zinc-300 dark:hover:prose-a:text-zinc-100 max-w-none"
|
||||||
>
|
>
|
||||||
<div set:html={post.content} />
|
<div set:html={post.content} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Next/Previous Navigation - Improved responsive design -->
|
<!-- Next/Previous Navigation - Improved responsive design -->
|
||||||
<div
|
<div
|
||||||
class="mt-12 grid grid-cols-1 gap-4 border-t border-zinc-200 pt-8 dark:border-zinc-800 sm:mt-16 sm:gap-6 sm:pt-12 md:grid-cols-2"
|
class="mt-12 grid grid-cols-1 gap-4 border-t border-zinc-200 pt-8 sm:mt-16 sm:gap-6 sm:pt-12 md:grid-cols-2 dark:border-zinc-800"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
prevPost && (
|
prevPost && (
|
||||||
<a
|
<a
|
||||||
href={`/blog/${prevPost.slug}`}
|
href={`/blog/${prevPost.slug}`}
|
||||||
class="group relative flex h-full flex-col overflow-hidden rounded-xl border border-zinc-200 p-4 transition-all duration-300 hover:-translate-y-1 hover:bg-zinc-50 dark:border-zinc-800 dark:hover:bg-zinc-800/50 sm:p-6"
|
class="group relative flex h-full flex-col overflow-hidden rounded-xl border border-zinc-200 p-4 transition-all duration-300 hover:-translate-y-1 hover:bg-zinc-50 sm:p-6 dark:border-zinc-800 dark:hover:bg-zinc-800/50"
|
||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-gradient-to-r from-zinc-100 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100 dark:from-zinc-800 dark:to-transparent" />
|
<div class="absolute inset-0 bg-gradient-to-r from-zinc-100 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100 dark:from-zinc-800 dark:to-transparent" />
|
||||||
<span class="relative z-10 mb-1 flex items-center gap-1 text-xs font-medium text-zinc-500 dark:text-zinc-400 sm:mb-2 sm:gap-2 sm:text-sm">
|
<span class="relative z-10 mb-1 flex items-center gap-1 text-xs font-medium text-zinc-500 sm:mb-2 sm:gap-2 sm:text-sm dark:text-zinc-400">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="20"
|
width="20"
|
||||||
@@ -76,7 +76,7 @@ const { post, nextPost, prevPost } = Astro.props;
|
|||||||
</svg>
|
</svg>
|
||||||
Previous Article
|
Previous Article
|
||||||
</span>
|
</span>
|
||||||
<h3 class="line-clamp-2 text-base font-medium text-zinc-900 transition-colors group-hover:text-zinc-700 dark:text-white dark:group-hover:text-zinc-300 sm:text-lg">
|
<h3 class="line-clamp-2 text-base font-medium text-zinc-900 transition-colors group-hover:text-zinc-700 sm:text-lg dark:text-white dark:group-hover:text-zinc-300">
|
||||||
{prevPost.title}
|
{prevPost.title}
|
||||||
</h3>
|
</h3>
|
||||||
</a>
|
</a>
|
||||||
@@ -86,10 +86,10 @@ const { post, nextPost, prevPost } = Astro.props;
|
|||||||
nextPost && (
|
nextPost && (
|
||||||
<a
|
<a
|
||||||
href={`/blog/${nextPost.slug}`}
|
href={`/blog/${nextPost.slug}`}
|
||||||
class="group relative flex h-full flex-col overflow-hidden rounded-xl border border-zinc-200 p-4 transition-all duration-300 hover:-translate-y-1 hover:bg-zinc-50 dark:border-zinc-800 dark:hover:bg-zinc-800/50 sm:p-6 md:text-right"
|
class="group relative flex h-full flex-col overflow-hidden rounded-xl border border-zinc-200 p-4 transition-all duration-300 hover:-translate-y-1 hover:bg-zinc-50 sm:p-6 md:text-right dark:border-zinc-800 dark:hover:bg-zinc-800/50"
|
||||||
>
|
>
|
||||||
<div class="absolute inset-0 bg-gradient-to-l from-zinc-100 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100 dark:from-zinc-800 dark:to-transparent" />
|
<div class="absolute inset-0 bg-gradient-to-l from-zinc-100 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100 dark:from-zinc-800 dark:to-transparent" />
|
||||||
<span class="relative z-10 mb-1 flex items-center gap-1 text-xs font-medium text-zinc-500 dark:text-zinc-400 sm:mb-2 sm:gap-2 sm:text-sm md:justify-end">
|
<span class="relative z-10 mb-1 flex items-center gap-1 text-xs font-medium text-zinc-500 sm:mb-2 sm:gap-2 sm:text-sm md:justify-end dark:text-zinc-400">
|
||||||
Next Article
|
Next Article
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -106,7 +106,7 @@ const { post, nextPost, prevPost } = Astro.props;
|
|||||||
<path d="m9 18 6-6-6-6" />
|
<path d="m9 18 6-6-6-6" />
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
<h3 class="line-clamp-2 text-base font-medium text-zinc-900 transition-colors group-hover:text-zinc-700 dark:text-white dark:group-hover:text-zinc-300 sm:text-lg">
|
<h3 class="line-clamp-2 text-base font-medium text-zinc-900 transition-colors group-hover:text-zinc-700 sm:text-lg dark:text-white dark:group-hover:text-zinc-300">
|
||||||
{nextPost.title}
|
{nextPost.title}
|
||||||
</h3>
|
</h3>
|
||||||
</a>
|
</a>
|
||||||
|
@@ -36,23 +36,23 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
<div class="relative mb-12 sm:mb-20">
|
<div class="relative mb-12 sm:mb-20">
|
||||||
<!-- Decorative elements -->
|
<!-- Decorative elements -->
|
||||||
<div
|
<div
|
||||||
class="animate-blob absolute -left-10 -top-10 h-48 w-48 rounded-full bg-zinc-100 opacity-30 blur-3xl dark:bg-zinc-800/30 sm:-left-20 sm:-top-20 sm:h-72 sm:w-72"
|
class="animate-blob absolute -top-10 -left-10 h-48 w-48 rounded-full bg-zinc-100 opacity-30 blur-3xl sm:-top-20 sm:-left-20 sm:h-72 sm:w-72 dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-blob animation-delay-2000 absolute -bottom-10 -right-10 h-48 w-48 rounded-full bg-zinc-200 opacity-30 blur-3xl dark:bg-zinc-800/30 sm:-bottom-20 sm:-right-20 sm:h-72 sm:w-72"
|
class="animate-blob animation-delay-2000 absolute -right-10 -bottom-10 h-48 w-48 rounded-full bg-zinc-200 opacity-30 blur-3xl sm:-right-20 sm:-bottom-20 sm:h-72 sm:w-72 dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative text-center">
|
<div class="relative text-center">
|
||||||
<h1
|
<h1
|
||||||
class="mb-4 text-3xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:text-4xl md:text-5xl"
|
class="mb-4 text-3xl font-bold tracking-tight text-zinc-900 sm:text-4xl md:text-5xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
Blog
|
Blog
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
class="mx-auto mb-6 max-w-2xl text-sm text-zinc-600 dark:text-zinc-400 sm:mb-10 sm:text-base"
|
class="mx-auto mb-6 max-w-2xl text-sm text-zinc-600 sm:mb-10 sm:text-base dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
Thoughts, ideas, and explorations on technology and selfhosting.
|
Thoughts, ideas, and explorations on technology and selfhosting.
|
||||||
</p>
|
</p>
|
||||||
@@ -65,23 +65,23 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
{
|
{
|
||||||
sortedPosts.length > 0 && (
|
sortedPosts.length > 0 && (
|
||||||
<div class="mb-8 sm:mb-12 md:col-span-12">
|
<div class="mb-8 sm:mb-12 md:col-span-12">
|
||||||
<article class="group relative overflow-hidden rounded-none border-b border-zinc-200 pb-6 dark:border-zinc-800 sm:pb-8">
|
<article class="group relative overflow-hidden rounded-none border-b border-zinc-200 pb-6 sm:pb-8 dark:border-zinc-800">
|
||||||
<div class="flex h-full flex-col gap-6 sm:gap-8 md:flex-row">
|
<div class="flex h-full flex-col gap-6 sm:gap-8 md:flex-row">
|
||||||
{sortedPosts[0].image && (
|
{sortedPosts[0].image && (
|
||||||
<div class="mx-auto h-60 w-full max-w-full overflow-hidden sm:h-80 sm:max-w-md md:mx-0 md:h-96 md:w-1/2">
|
<div class="mx-auto h-60 w-full max-w-full overflow-hidden sm:h-80 sm:max-w-md md:mx-0 md:h-96 md:w-1/2">
|
||||||
<img
|
<img
|
||||||
src={`${process.env.DIRECTUS_URL ?? 'https://directus.alexlebens.dev'}/assets/${sortedPosts[0].image}`}
|
src={`${process.env.DIRECTUS_URL ?? 'https://directus.alexlebens.dev'}/assets/${sortedPosts[0].image}`}
|
||||||
alt={sortedPosts[0].title}
|
alt={sortedPosts[0].title}
|
||||||
class="h-full w-full object-cover grayscale transition-all duration-700 hover:grayscale-0 group-hover:scale-105"
|
class="h-full w-full object-cover grayscale transition-all duration-700 group-hover:scale-105 hover:grayscale-0"
|
||||||
loading="eager"
|
loading="eager"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="flex flex-1 flex-col justify-center">
|
<div class="flex flex-1 flex-col justify-center">
|
||||||
<div class="mb-3 flex items-center justify-center gap-2 text-xs text-zinc-500 dark:text-zinc-400 sm:text-sm md:justify-start">
|
<div class="mb-3 flex items-center justify-center gap-2 text-xs text-zinc-500 sm:text-sm md:justify-start dark:text-zinc-400">
|
||||||
<span class="font-medium uppercase tracking-wider">Featured</span>
|
<span class="font-medium tracking-wider uppercase">Featured</span>
|
||||||
<span class="h-px w-6 bg-zinc-300 dark:bg-zinc-700 sm:w-8" />
|
<span class="h-px w-6 bg-zinc-300 sm:w-8 dark:bg-zinc-700" />
|
||||||
{sortedPosts[0].published_date && (
|
{sortedPosts[0].published_date && (
|
||||||
<time datetime={sortedPosts[0].published_date.toLocaleString()}>
|
<time datetime={sortedPosts[0].published_date.toLocaleString()}>
|
||||||
{sortedPosts[0].published_date.toLocaleString('en-US', {
|
{sortedPosts[0].published_date.toLocaleString('en-US', {
|
||||||
@@ -93,7 +93,7 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="mb-3 text-center text-2xl font-bold text-zinc-900 transition-colors group-hover:text-zinc-700 dark:text-zinc-100 dark:group-hover:text-zinc-300 sm:mb-4 sm:text-3xl md:text-left">
|
<h2 class="mb-3 text-center text-2xl font-bold text-zinc-900 transition-colors group-hover:text-zinc-700 sm:mb-4 sm:text-3xl md:text-left dark:text-zinc-100 dark:group-hover:text-zinc-300">
|
||||||
<a
|
<a
|
||||||
href={`/blog/${sortedPosts[0].slug}/`}
|
href={`/blog/${sortedPosts[0].slug}/`}
|
||||||
class="before:absolute before:inset-0"
|
class="before:absolute before:inset-0"
|
||||||
@@ -102,7 +102,7 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="mb-4 line-clamp-3 text-center text-sm text-zinc-600 dark:text-zinc-400 sm:mb-6 sm:text-base md:text-left">
|
<p class="mb-4 line-clamp-3 text-center text-sm text-zinc-600 sm:mb-6 sm:text-base md:text-left dark:text-zinc-400">
|
||||||
{sortedPosts[0].description}
|
{sortedPosts[0].description}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
{sortedPosts[0].tags && (
|
{sortedPosts[0].tags && (
|
||||||
<div class="flex flex-wrap justify-center gap-2 md:justify-start">
|
<div class="flex flex-wrap justify-center gap-2 md:justify-start">
|
||||||
{sortedPosts[0].tags.slice(0, 2).map((tag) => (
|
{sortedPosts[0].tags.slice(0, 2).map((tag) => (
|
||||||
<span class="border border-zinc-200 px-2 py-1 text-xs uppercase tracking-wider text-zinc-600 dark:border-zinc-800 dark:text-zinc-400 sm:px-3">
|
<span class="border border-zinc-200 px-2 py-1 text-xs tracking-wider text-zinc-600 uppercase sm:px-3 dark:border-zinc-800 dark:text-zinc-400">
|
||||||
{tag}
|
{tag}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
@@ -128,7 +128,7 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
<div class="relative md:col-span-3">
|
<div class="relative md:col-span-3">
|
||||||
<div class="mb-8 space-y-4 md:sticky md:top-24 md:mb-0">
|
<div class="mb-8 space-y-4 md:sticky md:top-24 md:mb-0">
|
||||||
<h3
|
<h3
|
||||||
class="mb-4 text-center text-lg font-medium uppercase tracking-wider text-zinc-900 dark:text-zinc-100 md:text-left"
|
class="mb-4 text-center text-lg font-medium tracking-wider text-zinc-900 uppercase md:text-left dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
Archive
|
Archive
|
||||||
</h3>
|
</h3>
|
||||||
@@ -141,12 +141,12 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
years.map((year, index) => (
|
years.map((year, index) => (
|
||||||
<a
|
<a
|
||||||
href={`#year-${year}`}
|
href={`#year-${year}`}
|
||||||
class={`mr-3 flex items-center whitespace-nowrap rounded-full border-b border-zinc-100 px-4 py-2 transition-colors hover:bg-zinc-50 dark:border-zinc-800 dark:hover:bg-zinc-900 md:mr-0 md:w-full md:whitespace-normal md:rounded-none md:px-0 md:py-3 ${index === 0 ? 'bg-zinc-50 dark:bg-zinc-800/50' : ''}`}
|
class={`mr-3 flex items-center rounded-full border-b border-zinc-100 px-4 py-2 whitespace-nowrap transition-colors hover:bg-zinc-50 md:mr-0 md:w-full md:rounded-none md:px-0 md:py-3 md:whitespace-normal dark:border-zinc-800 dark:hover:bg-zinc-900 ${index === 0 ? 'bg-zinc-50 dark:bg-zinc-800/50' : ''}`}
|
||||||
>
|
>
|
||||||
<span class="text-base font-medium text-zinc-900 dark:text-zinc-100 md:text-lg">
|
<span class="text-base font-medium text-zinc-900 md:text-lg dark:text-zinc-100">
|
||||||
{year}
|
{year}
|
||||||
</span>
|
</span>
|
||||||
<span class="ml-2 text-xs text-zinc-500 dark:text-zinc-400 md:ml-auto md:text-sm">
|
<span class="ml-2 text-xs text-zinc-500 md:ml-auto md:text-sm dark:text-zinc-400">
|
||||||
{postsByYear[year].length} post{postsByYear[year].length !== 1 ? 's' : ''}
|
{postsByYear[year].length} post{postsByYear[year].length !== 1 ? 's' : ''}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -161,7 +161,7 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
{
|
{
|
||||||
years.map((year) => (
|
years.map((year) => (
|
||||||
<div id={`year-${year}`} class="mb-12 scroll-mt-16 sm:mb-20">
|
<div id={`year-${year}`} class="mb-12 scroll-mt-16 sm:mb-20">
|
||||||
<h2 class="mb-6 border-b border-zinc-200 pb-3 text-center text-xl font-bold text-zinc-900 dark:border-zinc-800 dark:text-zinc-100 sm:mb-8 sm:pb-4 sm:text-2xl md:text-left">
|
<h2 class="mb-6 border-b border-zinc-200 pb-3 text-center text-xl font-bold text-zinc-900 sm:mb-8 sm:pb-4 sm:text-2xl md:text-left dark:border-zinc-800 dark:text-zinc-100">
|
||||||
{year}
|
{year}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -175,14 +175,14 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
<img
|
<img
|
||||||
src={`${process.env.DIRECTUS_URL ?? 'https://directus.alexlebens.dev'}/assets/${post.image}`}
|
src={`${process.env.DIRECTUS_URL ?? 'https://directus.alexlebens.dev'}/assets/${post.image}`}
|
||||||
alt={post.title}
|
alt={post.title}
|
||||||
class="h-full w-full object-cover grayscale transition-all duration-700 hover:grayscale-0 group-hover:scale-105"
|
class="h-full w-full object-cover grayscale transition-all duration-700 group-hover:scale-105 hover:grayscale-0"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="flex flex-1 flex-col">
|
<div class="flex flex-1 flex-col">
|
||||||
<div class="mb-2 flex flex-wrap items-center justify-center gap-3 text-xs text-zinc-500 dark:text-zinc-400 sm:mb-3 sm:gap-4 sm:text-sm md:justify-start">
|
<div class="mb-2 flex flex-wrap items-center justify-center gap-3 text-xs text-zinc-500 sm:mb-3 sm:gap-4 sm:text-sm md:justify-start dark:text-zinc-400">
|
||||||
{post.pubDate && (
|
{post.pubDate && (
|
||||||
<time
|
<time
|
||||||
datetime={post.published_date.toLocaleString()}
|
datetime={post.published_date.toLocaleString()}
|
||||||
@@ -196,25 +196,25 @@ const allTags = [...new Set(sortedPosts.flatMap((post) => post.tags || []))];
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="mb-2 text-center text-lg font-semibold text-zinc-900 transition-colors group-hover:text-zinc-700 dark:text-zinc-100 dark:group-hover:text-zinc-300 sm:mb-3 sm:text-xl md:text-left">
|
<h3 class="mb-2 text-center text-lg font-semibold text-zinc-900 transition-colors group-hover:text-zinc-700 sm:mb-3 sm:text-xl md:text-left dark:text-zinc-100 dark:group-hover:text-zinc-300">
|
||||||
<a href={`/blog/${post.slug}/`} class="before:absolute before:inset-0">
|
<a href={`/blog/${post.slug}/`} class="before:absolute before:inset-0">
|
||||||
{post.title}
|
{post.title}
|
||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<p class="mb-4 line-clamp-2 flex-grow text-center text-sm text-zinc-600 dark:text-zinc-400 md:text-left">
|
<p class="mb-4 line-clamp-2 flex-grow text-center text-sm text-zinc-600 md:text-left dark:text-zinc-400">
|
||||||
{post.description}
|
{post.description}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{post.tags && (
|
{post.tags && (
|
||||||
<div class="mt-auto flex flex-wrap justify-center gap-2 md:justify-start">
|
<div class="mt-auto flex flex-wrap justify-center gap-2 md:justify-start">
|
||||||
{post.tags.slice(0, 2).map((tag) => (
|
{post.tags.slice(0, 2).map((tag) => (
|
||||||
<span class="border border-zinc-200 px-2 py-1 text-xs uppercase tracking-wider text-zinc-600 dark:border-zinc-800 dark:text-zinc-400 sm:px-3">
|
<span class="border border-zinc-200 px-2 py-1 text-xs tracking-wider text-zinc-600 uppercase sm:px-3 dark:border-zinc-800 dark:text-zinc-400">
|
||||||
{tag}
|
{tag}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
{post.tags.length > 2 && (
|
{post.tags.length > 2 && (
|
||||||
<span class="border border-zinc-200 px-2 py-1 text-xs uppercase tracking-wider text-zinc-600 dark:border-zinc-800 dark:text-zinc-400 sm:px-3">
|
<span class="border border-zinc-200 px-2 py-1 text-xs tracking-wider text-zinc-600 uppercase sm:px-3 dark:border-zinc-800 dark:text-zinc-400">
|
||||||
+{post.tags.length - 2}
|
+{post.tags.length - 2}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
@@ -27,17 +27,17 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
<div class="relative mx-auto max-w-2xl">
|
<div class="relative mx-auto max-w-2xl">
|
||||||
<!-- Adjusted blob positions and sizes for better mobile appearance -->
|
<!-- Adjusted blob positions and sizes for better mobile appearance -->
|
||||||
<div
|
<div
|
||||||
class="animate-blob theme-transition-bg absolute -left-10 -top-10 h-40 w-40 rounded-full bg-zinc-100 opacity-50 blur-3xl dark:bg-zinc-800/50 sm:-left-20 sm:-top-20 sm:h-64 sm:w-64"
|
class="animate-blob theme-transition-bg absolute -top-10 -left-10 h-40 w-40 rounded-full bg-zinc-100 opacity-50 blur-3xl sm:-top-20 sm:-left-20 sm:h-64 sm:w-64 dark:bg-zinc-800/50"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-blob animation-delay-2000 theme-transition-bg absolute -bottom-10 -right-10 h-40 w-40 rounded-full bg-zinc-200 opacity-30 blur-3xl dark:bg-zinc-800/30 sm:-bottom-20 sm:-right-20 sm:h-64 sm:w-64"
|
class="animate-blob animation-delay-2000 theme-transition-bg absolute -right-10 -bottom-10 h-40 w-40 rounded-full bg-zinc-200 opacity-30 blur-3xl sm:-right-20 sm:-bottom-20 sm:h-64 sm:w-64 dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative text-center sm:text-left">
|
<div class="relative text-center sm:text-left">
|
||||||
<h1
|
<h1
|
||||||
class="theme-transition-color hero-text text-3xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:text-4xl md:text-5xl lg:text-6xl"
|
class="theme-transition-color hero-text text-3xl font-bold tracking-tight text-zinc-900 sm:text-4xl md:text-5xl lg:text-6xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
<span class="block">Writing on technology,</span>
|
<span class="block">Writing on technology,</span>
|
||||||
<span class="mt-1 block">development, and</span>
|
<span class="mt-1 block">development, and</span>
|
||||||
@@ -51,7 +51,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p
|
<p
|
||||||
class="theme-transition-color mx-auto mt-4 max-w-lg text-base leading-relaxed text-zinc-600 dark:text-zinc-400 sm:mx-0 sm:mt-6 sm:text-lg md:mt-8"
|
class="theme-transition-color mx-auto mt-4 max-w-lg text-base leading-relaxed text-zinc-600 sm:mx-0 sm:mt-6 sm:text-lg md:mt-8 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{global.about}
|
{global.about}
|
||||||
</p>
|
</p>
|
||||||
@@ -87,20 +87,20 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
|
|
||||||
<!-- Featured Post Section - Improved for mobile -->
|
<!-- Featured Post Section - Improved for mobile -->
|
||||||
<section
|
<section
|
||||||
class="theme-transition-all border-t border-zinc-100 px-4 py-10 dark:border-zinc-800 sm:px-6 sm:py-12 md:py-16"
|
class="theme-transition-all border-t border-zinc-100 px-4 py-10 sm:px-6 sm:py-12 md:py-16 dark:border-zinc-800"
|
||||||
>
|
>
|
||||||
<div class="mx-auto max-w-3xl">
|
<div class="mx-auto max-w-3xl">
|
||||||
<div
|
<div
|
||||||
class="mb-6 flex flex-col justify-between gap-4 sm:mb-8 sm:flex-row sm:items-center md:mb-12"
|
class="mb-6 flex flex-col justify-between gap-4 sm:mb-8 sm:flex-row sm:items-center md:mb-12"
|
||||||
>
|
>
|
||||||
<h2
|
<h2
|
||||||
class="theme-transition-color text-center text-xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:text-left sm:text-2xl md:text-3xl"
|
class="theme-transition-color text-center text-xl font-bold tracking-tight text-zinc-900 sm:text-left sm:text-2xl md:text-3xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
Recent Posts
|
Recent Posts
|
||||||
</h2>
|
</h2>
|
||||||
<a
|
<a
|
||||||
href="/blog"
|
href="/blog"
|
||||||
class="theme-transition-color group relative flex min-h-[44px] items-center justify-center self-center text-sm font-medium text-zinc-900 hover:text-zinc-700 dark:text-zinc-100 dark:hover:text-zinc-300 sm:self-auto"
|
class="theme-transition-color group relative flex min-h-[44px] items-center justify-center self-center text-sm font-medium text-zinc-900 hover:text-zinc-700 sm:self-auto dark:text-zinc-100 dark:hover:text-zinc-300"
|
||||||
>
|
>
|
||||||
<span class="flex items-center gap-1">
|
<span class="flex items-center gap-1">
|
||||||
View all posts
|
View all posts
|
||||||
@@ -129,7 +129,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
{
|
{
|
||||||
recentPosts.map((post, index) => (
|
recentPosts.map((post, index) => (
|
||||||
<article class="hover-3d theme-transition-element group relative mx-auto flex w-full max-w-sm flex-col items-start sm:mx-0">
|
<article class="hover-3d theme-transition-element group relative mx-auto flex w-full max-w-sm flex-col items-start sm:mx-0">
|
||||||
<div class="theme-transition-bg absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 dark:bg-zinc-800/50 sm:-inset-x-6 sm:rounded-2xl" />
|
<div class="theme-transition-bg absolute -inset-x-4 -inset-y-6 z-0 scale-95 bg-zinc-50 opacity-0 transition group-hover:scale-100 group-hover:opacity-100 sm:-inset-x-6 sm:rounded-2xl dark:bg-zinc-800/50" />
|
||||||
|
|
||||||
{post.image && (
|
{post.image && (
|
||||||
<div class="relative z-10 mb-4 aspect-video w-full overflow-hidden rounded-lg">
|
<div class="relative z-10 mb-4 aspect-video w-full overflow-hidden rounded-lg">
|
||||||
@@ -144,13 +144,13 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="theme-transition-color relative z-10 flex w-full flex-wrap items-center justify-center gap-x-3 gap-y-2 text-xs text-zinc-500 dark:text-zinc-400 sm:justify-start sm:gap-x-4">
|
<div class="theme-transition-color relative z-10 flex w-full flex-wrap items-center justify-center gap-x-3 gap-y-2 text-xs text-zinc-500 sm:justify-start sm:gap-x-4 dark:text-zinc-400">
|
||||||
<time datetime={post.published_date.toLocaleString()} class="font-medium">
|
<time datetime={post.published_date.toLocaleString()} class="font-medium">
|
||||||
<FormattedDate date={post.published_date} />
|
<FormattedDate date={post.published_date} />
|
||||||
</time>
|
</time>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 class="theme-transition-color relative z-10 mt-3 w-full text-center text-lg font-semibold tracking-tight text-zinc-900 transition-colors group-hover:text-zinc-700 dark:text-zinc-100 dark:group-hover:text-zinc-300 sm:text-left sm:text-xl">
|
<h3 class="theme-transition-color relative z-10 mt-3 w-full text-center text-lg font-semibold tracking-tight text-zinc-900 transition-colors group-hover:text-zinc-700 sm:text-left sm:text-xl dark:text-zinc-100 dark:group-hover:text-zinc-300">
|
||||||
<a
|
<a
|
||||||
href={`/blog/${post.slug}`}
|
href={`/blog/${post.slug}`}
|
||||||
class="flex min-h-[44px] items-center justify-center sm:justify-start"
|
class="flex min-h-[44px] items-center justify-center sm:justify-start"
|
||||||
@@ -160,7 +160,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
</a>
|
</a>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<p class="theme-transition-color relative z-10 mt-2 line-clamp-3 w-full text-center text-sm text-zinc-600 dark:text-zinc-400 sm:mt-3 sm:text-left">
|
<p class="theme-transition-color relative z-10 mt-2 line-clamp-3 w-full text-center text-sm text-zinc-600 sm:mt-3 sm:text-left dark:text-zinc-400">
|
||||||
{post.description}
|
{post.description}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
{post.tags.slice(0, 3).map((tag) => (
|
{post.tags.slice(0, 3).map((tag) => (
|
||||||
<a
|
<a
|
||||||
href={`/topics/${tag}`}
|
href={`/topics/${tag}`}
|
||||||
class="theme-transition-all inline-flex min-h-[28px] items-center rounded-full bg-zinc-100 px-2 py-1 text-xs font-medium text-zinc-800 transition-colors hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700 sm:px-3"
|
class="theme-transition-all inline-flex min-h-[28px] items-center rounded-full bg-zinc-100 px-2 py-1 text-xs font-medium text-zinc-800 transition-colors hover:bg-zinc-200 sm:px-3 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700"
|
||||||
>
|
>
|
||||||
#{tag}
|
#{tag}
|
||||||
</a>
|
</a>
|
||||||
@@ -184,13 +184,13 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
href={`/blog/${post.slug}`}
|
href={`/blog/${post.slug}`}
|
||||||
class="theme-transition-color relative z-10 mx-auto mt-3 flex min-h-[44px] items-center text-sm font-medium text-zinc-700 transition-colors group-hover:text-zinc-900 dark:text-zinc-300 dark:group-hover:text-zinc-100 sm:mx-0 sm:mt-4"
|
class="theme-transition-color relative z-10 mx-auto mt-3 flex min-h-[44px] items-center text-sm font-medium text-zinc-700 transition-colors group-hover:text-zinc-900 sm:mx-0 sm:mt-4 dark:text-zinc-300 dark:group-hover:text-zinc-100"
|
||||||
>
|
>
|
||||||
<span class="relative inline-block overflow-hidden">
|
<span class="relative inline-block overflow-hidden">
|
||||||
<span class="block transition-transform duration-300 group-hover:-translate-y-full">
|
<span class="block transition-transform duration-300 group-hover:-translate-y-full">
|
||||||
Read article
|
Read article
|
||||||
</span>
|
</span>
|
||||||
<span class="absolute left-0 top-0 translate-y-full whitespace-nowrap transition-transform duration-300 group-hover:translate-y-0">
|
<span class="absolute top-0 left-0 translate-y-full whitespace-nowrap transition-transform duration-300 group-hover:translate-y-0">
|
||||||
Explore now
|
Explore now
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -218,9 +218,9 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
<!-- Topics/Tags Section - Improved for mobile -->
|
<!-- Topics/Tags Section - Improved for mobile -->
|
||||||
{
|
{
|
||||||
allTags.length > 0 && (
|
allTags.length > 0 && (
|
||||||
<section class="theme-transition-all border-t border-zinc-100 px-4 py-10 dark:border-zinc-800 sm:px-6 sm:py-12 md:py-16">
|
<section class="theme-transition-all border-t border-zinc-100 px-4 py-10 sm:px-6 sm:py-12 md:py-16 dark:border-zinc-800">
|
||||||
<div class="mx-auto max-w-3xl">
|
<div class="mx-auto max-w-3xl">
|
||||||
<h2 class="theme-transition-color mb-6 text-center text-xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:mb-8 sm:text-left sm:text-2xl md:text-3xl">
|
<h2 class="theme-transition-color mb-6 text-center text-xl font-bold tracking-tight text-zinc-900 sm:mb-8 sm:text-left sm:text-2xl md:text-3xl dark:text-zinc-100">
|
||||||
Explore Topics
|
Explore Topics
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ const allTags = [...new Set(posts.flatMap((post) => post.tags || []))].slice(0,
|
|||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href={`/topics/${tag}`}
|
href={`/topics/${tag}`}
|
||||||
class="theme-transition-all group flex min-h-[80px] flex-col rounded-xl border border-zinc-200 p-3 transition-all duration-300 hover:bg-zinc-50 dark:border-zinc-800 dark:hover:bg-zinc-800/70 sm:min-h-[90px] sm:p-4 md:p-6"
|
class="theme-transition-all group flex min-h-[80px] flex-col rounded-xl border border-zinc-200 p-3 transition-all duration-300 hover:bg-zinc-50 sm:min-h-[90px] sm:p-4 md:p-6 dark:border-zinc-800 dark:hover:bg-zinc-800/70"
|
||||||
>
|
>
|
||||||
<div class="mb-2 flex items-start justify-between">
|
<div class="mb-2 flex items-start justify-between">
|
||||||
<span class="theme-transition-color mr-2 text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
<span class="theme-transition-color mr-2 text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
|
@@ -52,11 +52,11 @@ const relatedTags = [
|
|||||||
<!-- Header section -->
|
<!-- Header section -->
|
||||||
<div class="relative mb-10 sm:mb-16">
|
<div class="relative mb-10 sm:mb-16">
|
||||||
<div
|
<div
|
||||||
class="animate-blob absolute -left-20 -top-20 h-48 w-48 rounded-full bg-zinc-100 opacity-30 blur-3xl dark:bg-zinc-900/30 sm:h-64 sm:w-64"
|
class="animate-blob absolute -top-20 -left-20 h-48 w-48 rounded-full bg-zinc-100 opacity-30 blur-3xl sm:h-64 sm:w-64 dark:bg-zinc-900/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-blob animation-delay-2000 absolute -bottom-10 -right-10 h-36 w-36 rounded-full bg-zinc-200 opacity-20 blur-2xl dark:bg-zinc-900/20 sm:h-48 sm:w-48"
|
class="animate-blob animation-delay-2000 absolute -right-10 -bottom-10 h-36 w-36 rounded-full bg-zinc-200 opacity-20 blur-2xl sm:h-48 sm:w-48 dark:bg-zinc-900/20"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ const relatedTags = [
|
|||||||
class="mb-2 flex flex-col justify-center gap-4 sm:flex-row sm:items-center sm:justify-start"
|
class="mb-2 flex flex-col justify-center gap-4 sm:flex-row sm:items-center sm:justify-start"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="tag-icon mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-zinc-100 shadow-sm dark:bg-zinc-800 sm:mx-0"
|
class="tag-icon mx-auto flex h-12 w-12 items-center justify-center rounded-xl bg-zinc-100 shadow-sm sm:mx-0 dark:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -108,7 +108,7 @@ const relatedTags = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1
|
<h1
|
||||||
class="text-3xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:text-4xl"
|
class="text-3xl font-bold tracking-tight text-zinc-900 sm:text-4xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
<span class="relative">
|
<span class="relative">
|
||||||
#{tag}
|
#{tag}
|
||||||
@@ -122,7 +122,7 @@ const relatedTags = [
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p
|
<p
|
||||||
class="mx-auto mt-4 max-w-2xl text-base text-zinc-600 dark:text-zinc-400 sm:mx-0 sm:text-lg"
|
class="mx-auto mt-4 max-w-2xl text-base text-zinc-600 sm:mx-0 sm:text-lg dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
Exploring <span class="font-medium text-zinc-900 dark:text-zinc-100"
|
Exploring <span class="font-medium text-zinc-900 dark:text-zinc-100"
|
||||||
>{sortedPosts.length}</span
|
>{sortedPosts.length}</span
|
||||||
@@ -137,7 +137,7 @@ const relatedTags = [
|
|||||||
{
|
{
|
||||||
relatedTags.length > 0 && (
|
relatedTags.length > 0 && (
|
||||||
<div class="hide-scrollbar mb-8 overflow-x-auto pb-4 sm:mb-12">
|
<div class="hide-scrollbar mb-8 overflow-x-auto pb-4 sm:mb-12">
|
||||||
<h2 class="mb-3 text-center text-lg font-medium text-zinc-900 dark:text-zinc-100 sm:text-left">
|
<h2 class="mb-3 text-center text-lg font-medium text-zinc-900 sm:text-left dark:text-zinc-100">
|
||||||
Related topics
|
Related topics
|
||||||
</h2>
|
</h2>
|
||||||
<div class="flex flex-nowrap justify-center gap-2 sm:justify-start">
|
<div class="flex flex-nowrap justify-center gap-2 sm:justify-start">
|
||||||
@@ -162,7 +162,7 @@ const relatedTags = [
|
|||||||
<div class="relative space-y-6 sm:space-y-8">
|
<div class="relative space-y-6 sm:space-y-8">
|
||||||
{
|
{
|
||||||
sortedPosts.map((post) => (
|
sortedPosts.map((post) => (
|
||||||
<article class="hover-card group relative mx-auto flex max-w-2xl flex-col rounded-2xl border border-zinc-200 p-5 transition-all duration-300 hover:bg-zinc-50/80 hover:shadow-md dark:border-zinc-800 dark:hover:bg-zinc-900/50 sm:mx-0 sm:p-8">
|
<article class="hover-card group relative mx-auto flex max-w-2xl flex-col rounded-2xl border border-zinc-200 p-5 transition-all duration-300 hover:bg-zinc-50/80 hover:shadow-md sm:mx-0 sm:p-8 dark:border-zinc-800 dark:hover:bg-zinc-900/50">
|
||||||
<div class="absolute inset-0 rounded-2xl bg-gradient-to-br from-zinc-50/0 to-zinc-100/0 opacity-0 transition-opacity duration-500 group-hover:opacity-100 dark:from-zinc-900/0 dark:to-zinc-800/0" />
|
<div class="absolute inset-0 rounded-2xl bg-gradient-to-br from-zinc-50/0 to-zinc-100/0 opacity-0 transition-opacity duration-500 group-hover:opacity-100 dark:from-zinc-900/0 dark:to-zinc-800/0" />
|
||||||
|
|
||||||
<div class="flex flex-col gap-5 sm:flex-row sm:gap-6">
|
<div class="flex flex-col gap-5 sm:flex-row sm:gap-6">
|
||||||
@@ -178,7 +178,7 @@ const relatedTags = [
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<div class="mb-2 flex flex-wrap items-center justify-center gap-3 text-xs text-zinc-500 dark:text-zinc-400 sm:mb-3 sm:justify-start sm:gap-4 sm:text-sm">
|
<div class="mb-2 flex flex-wrap items-center justify-center gap-3 text-xs text-zinc-500 sm:mb-3 sm:justify-start sm:gap-4 sm:text-sm dark:text-zinc-400">
|
||||||
{post.published_date && (
|
{post.published_date && (
|
||||||
<time
|
<time
|
||||||
datetime={post.published_date.toLocaleString()}
|
datetime={post.published_date.toLocaleString()}
|
||||||
@@ -204,19 +204,19 @@ const relatedTags = [
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="mb-2 text-center text-xl font-semibold text-zinc-900 transition-colors group-hover:text-zinc-700 dark:text-zinc-100 dark:group-hover:text-zinc-300 sm:mb-3 sm:text-left sm:text-2xl">
|
<h2 class="mb-2 text-center text-xl font-semibold text-zinc-900 transition-colors group-hover:text-zinc-700 sm:mb-3 sm:text-left sm:text-2xl dark:text-zinc-100 dark:group-hover:text-zinc-300">
|
||||||
<a href={`/blog/${post.slug}/`} class="before:absolute before:inset-0">
|
<a href={`/blog/${post.slug}/`} class="before:absolute before:inset-0">
|
||||||
{post.title}
|
{post.title}
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="mb-4 line-clamp-2 text-center text-sm text-zinc-600 dark:text-zinc-400 sm:line-clamp-3 sm:text-left sm:text-base">
|
<p class="mb-4 line-clamp-2 text-center text-sm text-zinc-600 sm:line-clamp-3 sm:text-left sm:text-base dark:text-zinc-400">
|
||||||
{post.description}
|
{post.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4 flex flex-wrap items-end justify-center border-t border-zinc-100 pt-4 dark:border-zinc-800 sm:justify-between">
|
<div class="mt-4 flex flex-wrap items-end justify-center border-t border-zinc-100 pt-4 sm:justify-between dark:border-zinc-800">
|
||||||
{post.tags && post.tags.length > 0 && (
|
{post.tags && post.tags.length > 0 && (
|
||||||
<div class="mb-3 flex flex-wrap justify-center gap-2 sm:mb-0 sm:justify-start">
|
<div class="mb-3 flex flex-wrap justify-center gap-2 sm:mb-0 sm:justify-start">
|
||||||
{post.tags.slice(0, 3).map((postTag) => (
|
{post.tags.slice(0, 3).map((postTag) => (
|
||||||
@@ -239,7 +239,7 @@ const relatedTags = [
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div class="mx-auto sm:ml-auto sm:mr-0">
|
<div class="mx-auto sm:mr-0 sm:ml-auto">
|
||||||
<a
|
<a
|
||||||
href={`/blog/${post.slug}/`}
|
href={`/blog/${post.slug}/`}
|
||||||
class="inline-flex items-center text-sm font-medium text-zinc-700 transition-colors group-hover:text-zinc-900 dark:text-zinc-300 dark:group-hover:text-zinc-100"
|
class="inline-flex items-center text-sm font-medium text-zinc-700 transition-colors group-hover:text-zinc-900 dark:text-zinc-300 dark:group-hover:text-zinc-100"
|
||||||
@@ -250,7 +250,7 @@ const relatedTags = [
|
|||||||
<span class="block transition-transform duration-300 group-hover:-translate-y-full">
|
<span class="block transition-transform duration-300 group-hover:-translate-y-full">
|
||||||
Read article
|
Read article
|
||||||
</span>
|
</span>
|
||||||
<span class="absolute left-0 top-0 translate-y-full whitespace-nowrap transition-transform duration-300 group-hover:translate-y-0">
|
<span class="absolute top-0 left-0 translate-y-full whitespace-nowrap transition-transform duration-300 group-hover:translate-y-0">
|
||||||
Explore now
|
Explore now
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -281,14 +281,14 @@ const relatedTags = [
|
|||||||
{
|
{
|
||||||
sortedPosts.length === 0 && (
|
sortedPosts.length === 0 && (
|
||||||
<div class="py-12 text-center sm:py-20">
|
<div class="py-12 text-center sm:py-20">
|
||||||
<div class="mb-4 inline-flex h-16 w-16 items-center justify-center rounded-full bg-zinc-100 dark:bg-zinc-800 sm:mb-6 sm:h-20 sm:w-20">
|
<div class="mb-4 inline-flex h-16 w-16 items-center justify-center rounded-full bg-zinc-100 sm:mb-6 sm:h-20 sm:w-20 dark:bg-zinc-800">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="h-8 w-8 text-zinc-500 dark:text-zinc-400 sm:h-10 sm:w-10"
|
class="h-8 w-8 text-zinc-500 sm:h-10 sm:w-10 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
@@ -297,7 +297,7 @@ const relatedTags = [
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="mb-2 text-xl font-semibold text-zinc-900 dark:text-zinc-100 sm:text-2xl">
|
<h2 class="mb-2 text-xl font-semibold text-zinc-900 sm:text-2xl dark:text-zinc-100">
|
||||||
No posts found
|
No posts found
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-zinc-600 dark:text-zinc-400">There are no posts with this tag yet.</p>
|
<p class="text-zinc-600 dark:text-zinc-400">There are no posts with this tag yet.</p>
|
||||||
|
@@ -34,20 +34,20 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
|||||||
<!-- Enhanced header section with animated elements - improved for mobile -->
|
<!-- Enhanced header section with animated elements - improved for mobile -->
|
||||||
<div class="theme-transition-element relative mb-8 text-center sm:mb-12 md:mb-16">
|
<div class="theme-transition-element relative mb-8 text-center sm:mb-12 md:mb-16">
|
||||||
<div
|
<div
|
||||||
class="animate-blob theme-transition-bg absolute -left-16 -top-16 h-36 w-36 rounded-full bg-zinc-100 opacity-50 blur-3xl dark:bg-zinc-800/50 sm:h-48 sm:w-48 md:h-72 md:w-72"
|
class="animate-blob theme-transition-bg absolute -top-16 -left-16 h-36 w-36 rounded-full bg-zinc-100 opacity-50 blur-3xl sm:h-48 sm:w-48 md:h-72 md:w-72 dark:bg-zinc-800/50"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-blob animation-delay-2000 theme-transition-bg absolute -bottom-16 -right-16 h-36 w-36 rounded-full bg-zinc-200 opacity-30 blur-3xl dark:bg-zinc-800/30 sm:h-48 sm:w-48 md:h-72 md:w-72"
|
class="animate-blob animation-delay-2000 theme-transition-bg absolute -right-16 -bottom-16 h-36 w-36 rounded-full bg-zinc-200 opacity-30 blur-3xl sm:h-48 sm:w-48 md:h-72 md:w-72 dark:bg-zinc-800/30"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="animate-blob animation-delay-4000 theme-transition-bg absolute right-8 top-8 h-24 w-24 rounded-full bg-zinc-100/30 opacity-40 blur-2xl dark:bg-zinc-700/20 sm:h-32 sm:w-32 md:h-40 md:w-40"
|
class="animate-blob animation-delay-4000 theme-transition-bg absolute top-8 right-8 h-24 w-24 rounded-full bg-zinc-100/30 opacity-40 blur-2xl sm:h-32 sm:w-32 md:h-40 md:w-40 dark:bg-zinc-700/20"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1
|
<h1
|
||||||
class="theme-transition-color relative mb-3 text-3xl font-bold tracking-tight text-zinc-900 dark:text-zinc-100 sm:mb-4 sm:text-4xl md:mb-6 md:text-5xl lg:text-6xl"
|
class="theme-transition-color relative mb-3 text-3xl font-bold tracking-tight text-zinc-900 sm:mb-4 sm:text-4xl md:mb-6 md:text-5xl lg:text-6xl dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
<span class="relative inline-block">
|
<span class="relative inline-block">
|
||||||
<span class="relative inline-block">
|
<span class="relative inline-block">
|
||||||
@@ -60,13 +60,13 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
|||||||
<span class="relative inline-block">
|
<span class="relative inline-block">
|
||||||
Topics
|
Topics
|
||||||
<span
|
<span
|
||||||
class="animate-underline theme-transition-bg absolute -bottom-1 left-0 h-0.5 w-full origin-left transform bg-gradient-to-r from-zinc-400 to-zinc-600 dark:from-zinc-600 dark:to-zinc-400 sm:-bottom-2 sm:h-1"
|
class="animate-underline theme-transition-bg absolute -bottom-1 left-0 h-0.5 w-full origin-left transform bg-gradient-to-r from-zinc-400 to-zinc-600 sm:-bottom-2 sm:h-1 dark:from-zinc-600 dark:to-zinc-400"
|
||||||
></span>
|
></span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p
|
<p
|
||||||
class="theme-transition-color relative mx-auto max-w-2xl text-sm text-zinc-600 dark:text-zinc-400 sm:text-base md:text-lg lg:text-xl"
|
class="theme-transition-color relative mx-auto max-w-2xl text-sm text-zinc-600 sm:text-base md:text-lg lg:text-xl dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
Discover content organized by your interests
|
Discover content organized by your interests
|
||||||
</p>
|
</p>
|
||||||
@@ -75,14 +75,14 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
|||||||
{
|
{
|
||||||
tags.length === 0 ? (
|
tags.length === 0 ? (
|
||||||
<div class="theme-transition-element py-8 text-center sm:py-12 md:py-16">
|
<div class="theme-transition-element py-8 text-center sm:py-12 md:py-16">
|
||||||
<div class="theme-transition-bg mb-3 inline-flex h-16 w-16 items-center justify-center rounded-full bg-zinc-100 shadow-inner dark:bg-zinc-800 sm:mb-4 sm:h-20 sm:w-20 md:mb-6 md:h-24 md:w-24">
|
<div class="theme-transition-bg mb-3 inline-flex h-16 w-16 items-center justify-center rounded-full bg-zinc-100 shadow-inner sm:mb-4 sm:h-20 sm:w-20 md:mb-6 md:h-24 md:w-24 dark:bg-zinc-800">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="theme-transition-color h-8 w-8 text-zinc-500 dark:text-zinc-400 sm:h-10 sm:w-10 md:h-12 md:w-12"
|
class="theme-transition-color h-8 w-8 text-zinc-500 sm:h-10 sm:w-10 md:h-12 md:w-12 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
@@ -92,21 +92,21 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
|||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="theme-transition-color text-lg font-medium text-zinc-800 dark:text-zinc-200 sm:text-xl md:text-2xl">
|
<p class="theme-transition-color text-lg font-medium text-zinc-800 sm:text-xl md:text-2xl dark:text-zinc-200">
|
||||||
No tags found yet.
|
No tags found yet.
|
||||||
</p>
|
</p>
|
||||||
<p class="theme-transition-color mt-2 text-xs text-zinc-500 dark:text-zinc-500 sm:text-sm md:text-base">
|
<p class="theme-transition-color mt-2 text-xs text-zinc-500 sm:text-sm md:text-base dark:text-zinc-500">
|
||||||
Check back later for categorized content.
|
Check back later for categorized content.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div class="flex w-full justify-center">
|
<div class="flex w-full justify-center">
|
||||||
<div class="tag-cloud hover-3d glass theme-transition-all relative w-full rounded-lg border border-zinc-100 bg-white/50 p-3 backdrop-blur-sm dark:border-zinc-800 dark:bg-zinc-900/50 sm:rounded-xl sm:p-4 md:rounded-2xl md:p-6 lg:rounded-3xl lg:p-8">
|
<div class="tag-cloud hover-3d glass theme-transition-all relative w-full rounded-lg border border-zinc-100 bg-white/50 p-3 backdrop-blur-sm sm:rounded-xl sm:p-4 md:rounded-2xl md:p-6 lg:rounded-3xl lg:p-8 dark:border-zinc-800 dark:bg-zinc-900/50">
|
||||||
<div class="bg-grid-pattern theme-transition-bg absolute inset-0 opacity-5 dark:opacity-10" />
|
<div class="bg-grid-pattern theme-transition-bg absolute inset-0 opacity-5 dark:opacity-10" />
|
||||||
<div class="theme-transition-bg absolute -right-8 -top-8 h-20 w-20 rounded-full bg-gradient-to-br from-zinc-200/30 to-zinc-300/20 blur-xl dark:from-zinc-700/20 dark:to-zinc-800/10 sm:h-24 sm:w-24 md:h-32 md:w-32 lg:h-40 lg:w-40" />
|
<div class="theme-transition-bg absolute -top-8 -right-8 h-20 w-20 rounded-full bg-gradient-to-br from-zinc-200/30 to-zinc-300/20 blur-xl sm:h-24 sm:w-24 md:h-32 md:w-32 lg:h-40 lg:w-40 dark:from-zinc-700/20 dark:to-zinc-800/10" />
|
||||||
<div class="theme-transition-bg absolute -bottom-8 -left-8 h-20 w-20 rounded-full bg-gradient-to-tl from-zinc-200/30 to-zinc-300/20 blur-xl dark:from-zinc-700/20 dark:to-zinc-800/10 sm:h-24 sm:w-24 md:h-32 md:w-32 lg:h-40 lg:w-40" />
|
<div class="theme-transition-bg absolute -bottom-8 -left-8 h-20 w-20 rounded-full bg-gradient-to-tl from-zinc-200/30 to-zinc-300/20 blur-xl sm:h-24 sm:w-24 md:h-32 md:w-32 lg:h-40 lg:w-40 dark:from-zinc-700/20 dark:to-zinc-800/10" />
|
||||||
|
|
||||||
<h2 class="theme-transition-color mb-3 text-center text-lg font-bold text-zinc-900 dark:text-zinc-100 sm:mb-4 sm:text-xl md:mb-6 md:text-2xl lg:mb-8 lg:text-3xl">
|
<h2 class="theme-transition-color mb-3 text-center text-lg font-bold text-zinc-900 sm:mb-4 sm:text-xl md:mb-6 md:text-2xl lg:mb-8 lg:text-3xl dark:text-zinc-100">
|
||||||
Popular Topics
|
Popular Topics
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -114,23 +114,23 @@ const sortedTags = [...tagObjects].sort((a, b) => b.count - a.count);
|
|||||||
{sortedTags.map((tag) => (
|
{sortedTags.map((tag) => (
|
||||||
<a
|
<a
|
||||||
href={`/topics/${tag.name}`}
|
href={`/topics/${tag.name}`}
|
||||||
class="theme-transition-element theme-ripple group relative min-w-0 flex-grow overflow-hidden rounded-md border border-zinc-200 transition-all duration-300 hover:scale-[1.03] hover:border-zinc-300 hover:shadow-md active:scale-95 dark:border-zinc-800 dark:hover:border-zinc-700 sm:rounded-lg sm:hover:shadow-lg md:rounded-xl"
|
class="theme-transition-element theme-ripple group relative min-w-0 flex-grow overflow-hidden rounded-md border border-zinc-200 transition-all duration-300 hover:scale-[1.03] hover:border-zinc-300 hover:shadow-md active:scale-95 sm:rounded-lg sm:hover:shadow-lg md:rounded-xl dark:border-zinc-800 dark:hover:border-zinc-700"
|
||||||
style={`--tag-hue: ${tag.hue};`}
|
style={`--tag-hue: ${tag.hue};`}
|
||||||
>
|
>
|
||||||
<div class="theme-transition-bg absolute inset-0 bg-gradient-to-br from-zinc-50/90 to-zinc-100/90 opacity-100 transition-opacity group-hover:opacity-95 dark:from-zinc-800/90 dark:to-zinc-900/90" />
|
<div class="theme-transition-bg absolute inset-0 bg-gradient-to-br from-zinc-50/90 to-zinc-100/90 opacity-100 transition-opacity group-hover:opacity-95 dark:from-zinc-800/90 dark:to-zinc-900/90" />
|
||||||
|
|
||||||
<div class="xxxs:px-2 xxs:px-2 xs:px-2 xxxs:py-2 xxs:py-2 xs:py-2 xxs:gap-2 relative flex w-full items-center gap-1.5 px-1.5 py-1.5 sm:px-3 sm:py-3 md:px-4 md:py-4">
|
<div class="xxxs:px-2 xxs:px-2 xs:px-2 xxxs:py-2 xxs:py-2 xs:py-2 xxs:gap-2 relative flex w-full items-center gap-1.5 px-1.5 py-1.5 sm:px-3 sm:py-3 md:px-4 md:py-4">
|
||||||
<div class="xxxs:w-6 xxxs:h-6 xxs:w-6 xxs:h-6 xs:w-7 xs:h-7 group-hover:bg-accent/20 dark:group-hover:bg-accent/20 group-hover:text-accent-dark dark:group-hover:text-accent-light theme-transition-all flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-zinc-100 text-zinc-700 shadow-sm transition-all duration-300 dark:bg-zinc-800 dark:text-zinc-300 sm:h-8 sm:w-8 md:h-10 md:w-10">
|
<div class="xxxs:w-6 xxxs:h-6 xxs:w-6 xxs:h-6 xs:w-7 xs:h-7 group-hover:bg-accent/20 dark:group-hover:bg-accent/20 group-hover:text-accent-dark dark:group-hover:text-accent-light theme-transition-all flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-zinc-100 text-zinc-700 shadow-sm transition-all duration-300 sm:h-8 sm:w-8 md:h-10 md:w-10 dark:bg-zinc-800 dark:text-zinc-300">
|
||||||
<span class="xxxs:text-xs xxs:text-xs xs:text-sm text-xs font-semibold sm:text-base md:text-lg">
|
<span class="xxxs:text-xs xxs:text-xs xs:text-sm text-xs font-semibold sm:text-base md:text-lg">
|
||||||
#
|
#
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="min-w-0 flex-1 overflow-hidden">
|
<div class="min-w-0 flex-1 overflow-hidden">
|
||||||
<h3 class="xxxs:text-xs xxs:text-xs xs:text-xs theme-transition-color truncate hyphens-auto break-words text-[10px] font-bold text-zinc-900 transition-colors group-hover:text-zinc-700 dark:text-zinc-100 dark:group-hover:text-zinc-300 sm:text-sm md:text-base">
|
<h3 class="xxxs:text-xs xxs:text-xs xs:text-xs theme-transition-color truncate text-[10px] font-bold break-words hyphens-auto text-zinc-900 transition-colors group-hover:text-zinc-700 sm:text-sm md:text-base dark:text-zinc-100 dark:group-hover:text-zinc-300">
|
||||||
{tag.name}
|
{tag.name}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="xxxs:text-[9px] xxs:text-[9px] xs:text-[10px] theme-transition-color truncate text-[8px] text-zinc-500 dark:text-zinc-400 sm:text-xs md:text-xs">
|
<p class="xxxs:text-[9px] xxs:text-[9px] xs:text-[10px] theme-transition-color truncate text-[8px] text-zinc-500 sm:text-xs md:text-xs dark:text-zinc-400">
|
||||||
{tag.count} article{tag.count !== 1 ? 's' : ''}
|
{tag.count} article{tag.count !== 1 ? 's' : ''}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* Remove all the complex mobile menu styles and keep only what's necessary */
|
/* Remove all the complex mobile menu styles and keep only what's necessary */
|
||||||
@import "tailwindcss";
|
@import 'tailwindcss';
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
|
Reference in New Issue
Block a user